вторник, 13 октября 2009 г.

Exceptions handling and reflection

There are Java reflection developed in such way that you cannot handle any exception which was throwed in the object method you call by invoke. It's not good, but you can handle it by using next solutions:
1. Present exceptions in target object not as exception in full-mean but as data-objects which can be accessed by external interfaces, for example:



class X...

public Throwable setException( Throwable e ) {
this.exception = e;
}

public Throwable getException() {
return this.exception;
}

public void doAction( int d ) {
if ( d > 2 ) {
// In a normally case we had been probably used throw to pop exception, but it's not
// impossible to handle it under invokation, so...
this.setException("Wrong value");
}
}
}

class D...

public static void main() throws Throwable {
X.getClass().getMethods("doAction", null).invoke( new X(), null );
}
}



It's probably some bit interface beauty and introduce global state, but it's work...

2. Java not completely "eat" all exceptions, it only not handles them so we cannot work with theirs semantics. But if it's not very important to you to handle concrete exceptions but know that execution fails in some method its will be enough for you to handle ExceptionInInitializerError, which Java throws in such cases.

3. Another more radical way to handle such exceptions is - Aspect-Oriented Programming :-)

AOP provides powerful techniques to work with such situations.


pointcut exceptionHandler(Exception e): handler(Exception+) && args(e);

after(Exception e): exceptionHandler(e)
{
ExceptionManager.Publish (e)
}



Read more about AspectJ, and good article about AOP exceptions handling with Spring

J2EE and MySQL

Few days ago I had a problem when working with MySQL Connector/J JDBC connector, and it's was so strange for me as for beginner J2EE developer so I decided to write about it for peoples that have same problem.

First of all the exception stack trace can be something like:


java.net.SocketException: java.security.AccessControlException: access denied (java.net.SocketPermission 127.0.0.1:3306 connect,resolve)
at com.mysql.jdbc.StandardSocketFactory.unwrapExceptionToProperClassAndThrowIt(StandardSocketFactory.java:407)
at com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:268)
at com.mysql.jdbc.MysqlIO.(MysqlIO.java:271)
at com.mysql.jdbc.Connection.createNewIO(Connection.java:2921)
at com.mysql.jdbc.Connection.(Connection.java:1555)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:285)
at java.sql.DriverManager.getConnection(DriverManager.java:620)
at java.sql.DriverManager.getConnection(DriverManager.java:222)




First of all, this problem may happens as simple JDBC authorization error such like "Permission denied" which happens in sendAuth() (or sendAuth441() ) connection stage. But there isn't problem of your connection or credentials it's only told you that you not given permissions to use socket connection to your MySQL connector JAR under J2EE container :-)

You can give it in a simple way configuring security.police file in your J2EE application server configuration directory ( in your domain configuration directory if you use Sun Glassfish ):



grant codeBase "${path_to_your_mysql_connector_jar}!/-" {
permission java.net.SocketPermission ${your_host}, "connect";
}



Do not forget that your problem can be difference than JAR permission ;-)