users@glassfish.java.net

Exception Interceptor

From: <glassfish_at_javadesktop.org>
Date: Thu, 25 Jun 2009 08:25:20 PDT

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?

ejb-jar.xml:
[code]
<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>
[/code]

ExceptionHandler.java:
[code]
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);
        }
    }
}
[/code]

ServerSideException.java:
[code]
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;
    }
}
[/code]
[Message sent by forum member 'culli' (culli)]

http://forums.java.net/jive/thread.jspa?messageID=352965