|
Replies:
12
-
Last Post:
Jun 29, 2009 12:59 PM
by: culli
|
|
|
|
|
|
|
Exception Interceptor
Posted:
Jun 25, 2009 8:25 AM
|
|
|
I have a swing client that I'm trying to keep from deploying the hibernate jars with. There is a problem when hibernate exceptions happen on the server and come across to the client, it cannot deserialize them because the right classes aren't available. So to try to work around that I created an interceptor like the code below which converts the an exception's stack trace to text and makes it into a ServerSideException. The problem is all I get is "transaction marked for rollback" and never see my ServerSideException on the client. If I step through the code, I can see that the Hibernate exception (such as an InvalidValue) is occurring and getting converted to a ServerSideException. Then on the client the exception chain is: ExecutionException->EJBException->RemoteException with the message: "Transaction aborted; nested exception is: javax.transaction.RollbackException: Transaction marked for rollback." I have tried with and without the @ApplicationException, and with and without the rollback=false on it.
Is there a way to insulate the client this way?
Edit: Glassfish 2.1 (9.1.1) (build b60e-fcs)
Edit: I think this is a bug in Glassfish. EJB 3.0 spec says: 12.3.2 Exceptions Business method interceptor methods may throw runtime exceptions or application exceptions that are allowed in the throws clause of the business method. AroundInvoke methods are allowed to catch and suppress exceptions and recover by calling proceed(). AroundInvoke methods are allowed to throw runtime exceptions or any checked exceptions that the business method allows within its throws clause.
ejb-jar.xml:
<ejb-jar xmlns = "http://java.sun.com/xml/ns/javaee"
version = "3.0"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd">
<interceptors>
<interceptor>
<interceptor-class>
com.foo.ExceptionHandler
</interceptor-class>
</interceptor>
</interceptors>
<assembly-descriptor>
<interceptor-binding>
<ejb-name>*</ejb-name>
<interceptor-class>com.foo.ExceptionHandler</interceptor-class>
</interceptor-binding>
</assembly-descriptor>
</ejb-jar>
ExceptionHandler.java:
package com.foo;
import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;
import javax.persistence.PersistenceException;
public class ExceptionHandler {
@AroundInvoke
public Object handleException(InvocationContext ctx) throws Exception {
try {
return ctx.proceed();
} catch (Throwable t) {
t.printStackTrace();
throw new ServerSideException(t);
}
}
}
ServerSideException.java:
package com.foo;
import javax.ejb.ApplicationException;
@ApplicationException(rollback=true)
public class ServerSideException extends Exception {
private String errorClass;
private String stackTraceString;
public ServerSideException(Throwable t) {
super(t.getMessage());
this.errorClass = t.getClass().getName();
StringBuilder builder = new StringBuilder();
for (StackTraceElement element : t.getStackTrace()) {
builder.append(element.toString());
builder.append("\n");
}
this.stackTraceString = builder.toString();
}
public String getErrorClass() {
return errorClass;
}
public String getStackTraceString() {
return stackTraceString;
}
}
Message was edited by: culli
Message was edited by: culli
|
|
|
|
|
|
|
Re: Exception Interceptor
Posted:
Jun 25, 2009 2:43 PM
in response to: culli
|
|
|
It sounds as if the underlying persistence manager is marking the transaction for rollback. The container will still attempt to commit any transaction it started, and if the rollback fails a system exception will be thrown to the client. If you want to protect against this case you could perform the transactional work in a bean-managed transaction.
|
|
|
|
|
|
|
|
Re: Exception Interceptor
Posted:
Jun 26, 2009 8:12 AM
in response to: ksak
|
|
|
Maybe I'm missing something, but the point of what I'm doing is that every remote call that throws an exception should change that exception into something that is more friendly to the client, and that can be deserialized consistently, without 100 gigabytes of dependencies. I don't want to code every bean with a bean managed transaction. It should work the way I have set it up according to the spec, so it's a bug in GlassFish in my opinion.
|
|
|
|
|
|
|
|
Re: Exception Interceptor
Posted:
Jun 27, 2009 10:08 AM
in response to: culli
|
|
|
Shooting from the hip here but -
I believe the exception you're catching has 1 or more nested exceptions inside of it. To get to these you'll need to call t.getcause() in ServerSideException's constructor and fillin the stack traces from each nestedexception. It's like traversing thru a linked list.
Throwable getCause() Returns the cause of this throwable or null if the cause is nonexistent or unknown.
|
|
|
|
|
|
|
|
Re: Exception Interceptor
Posted:
Jun 27, 2009 5:06 PM
in response to: twk12345
|
|
|
Yes I have an unwrapper method that does that. That's not the point of my post though, so for simplicty I left it out.
Is there anyone that can address the point about the rollbacks that probably should not be happening?
|
|
|
|
|
|
|
|
Re: Exception Interceptor
Posted:
Jun 29, 2009 10:38 AM
in response to: culli
|
|
|
Can you check if there is no exception in the server.log from commit/rollback? If there is, it's not clear which exception should be propagated to the client - the rollback exception or the application exception.
thanks, -marina
glassfish@javadesktop.org wrote: > Yes I have an unwrapper method that does that. That's not the point of my post though, so for simplicty I left it out. > > Is there anyone that can address the point about the rollbacks that probably should not be happening? > [Message sent by forum member 'culli' (culli)] > > http://forums.java.net/jive/thread.jspa?messageID=353286 > > --------------------------------------------------------------------- > To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net > For additional commands, e-mail: users-help@glassfish.dev.java.net >
--------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net For additional commands, e-mail: users-help@glassfish.dev.java.net
|
|
|
|
|
|
|
|
Re: Exception Interceptor
Posted:
Jun 29, 2009 11:22 AM
in response to: Marina Vatkina
|
|
|
I can verify that no other exception is showing in the log except the "marked for rollback". I turned everything up to Trace in the logging at one point to try to get more detail, but after a lot of looking I didn't find anything that helped.
If I turn off the @AroundInvoke interceptor, the real exceptions come through just fine, such as Hibernate Validator's InvalidStateException. With the interceptor catching that and throwing my ServerSideException, then only the rollback exception comes through.
|
|
|
|
|
|
|
|
Re: Exception Interceptor
Posted:
Jun 29, 2009 11:25 AM
in response to: culli
|
|
|
Is transaction marked for rollback at the time you catch the exception?
thanks, -marina
glassfish@javadesktop.org wrote: > I can verify that no other exception is showing in the log except the "marked for rollback". I turned everything up to Trace in the logging at one point to try to get more detail, but after a lot of looking I didn't find anything that helped. > > If I turn off the @AroundInvoke interceptor, the real exceptions come through just fine, such as Hibernate Validator's InvalidStateException. With the interceptor catching that and throwing my ServerSideException, then only the rollback exception comes through. > [Message sent by forum member 'culli' (culli)] > > http://forums.java.net/jive/thread.jspa?messageID=353453 > > --------------------------------------------------------------------- > To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net > For additional commands, e-mail: users-help@glassfish.dev.java.net >
--------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net For additional commands, e-mail: users-help@glassfish.dev.java.net
|
|
|
|
|
|
|
|
Re: Exception Interceptor
Posted:
Jun 29, 2009 12:12 PM
in response to: Marina Vatkina
|
|
|
How do I find that out inside the @AroundInvoke method (handleException in my case)? I have the InvocationContext, but I'm not seeing how to get information about the transaction from that level.
|
|
|
|
|
|
|
|
Re: Exception Interceptor
Posted:
Jun 29, 2009 12:20 PM
in response to: culli
|
|
|
Good question. Can you try looking up the TransactionSynchronizationRegistry?
thanks, -marina
glassfish@javadesktop.org wrote: > How do I find that out inside the @AroundInvoke method (handleException in my case)? I have the InvocationContext, but I'm not seeing how to get information about the transaction from that level. > [Message sent by forum member 'culli' (culli)] > > http://forums.java.net/jive/thread.jspa?messageID=353466 > > --------------------------------------------------------------------- > To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net > For additional commands, e-mail: users-help@glassfish.dev.java.net >
--------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net For additional commands, e-mail: users-help@glassfish.dev.java.net
|
|
|
|
|
|
|
|
Re: Exception Interceptor
Posted:
Jun 29, 2009 12:59 PM
in response to: Marina Vatkina
|
|
|
Awesome! session.setRollbackOnly() in my catch blocks solves this. Thanks!
|
|
|
|
|
|
|
|
Re: Exception Interceptor
Posted:
Jun 29, 2009 12:23 PM
in response to: culli
|
|
|
Nevermind, I figured that part out: @Resource private javax.ejb.SessionContext session;
Which shows that session.getRollbackOnly() == false.
|
|
|
|
|
|
|
|
Re: Exception Interceptor
Posted:
Jun 29, 2009 12:42 PM
in response to: culli
|
|
|
Then the commit/rollback fails and that what the client is told about. I added logging of the exception in beforeCompletion but I'm not sure if it made it to v2.1, so try setting Hibernate log levels to finest to see the actual cause. There is also an open bug to propagate the exception from the beforeCompletion to the client that should be fixed in v3.
Check if setting rollback only solves your problem.
HTH, -marina
glassfish@javadesktop.org wrote: > Nevermind, I figured that part out: > @Resource > private javax.ejb.SessionContext session; > > > Which shows that session.getRollbackOnly() == false. > [Message sent by forum member 'culli' (culli)] > > http://forums.java.net/jive/thread.jspa?messageID=353469 > > --------------------------------------------------------------------- > To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net > For additional commands, e-mail: users-help@glassfish.dev.java.net >
--------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net For additional commands, e-mail: users-help@glassfish.dev.java.net
|
|
|
|
|