4 Replies Latest reply on Jul 1, 2007 2:52 PM by gogoasa

    hibernate exception not hidden from ejb client

    gogoasa

      Hello,

      I use the remote ejb/CommandServiceBean ejb in order to query an enterprise (EJB) jBPM deployment.

      The EJB client only depends on the jBPM jar (for the various Command implementations) and on the JBoss client jar. If a Hibernate exceptin occurs, it is wrapped by a JBPMException and rethrown. When deserialiezed on the client side (which does not have a Hibernate dependency), a ClassNotFoundException occurs.

      Here is the exception handling code in the EJB :

      catch (Exception e) {
       throw new JbpmException("couldn't execute "+command, e);
      }


      I think the CommandServiceBean should not wrap internal implementation-specific exceptions; it should instead simply copy the stack trace and throw a new implementation-independent exception which contains the exception trace without containing the causes themselves. That typically avoids ClassNotFoundExceptions without losing exception history.

      java.lang.reflect.UndeclaredThrowableException
       at $Proxy1.execute(Unknown Source)
       at fr.bnf.jbpm.client.GetInvalidDocumentsTest.testExecute(GetInvalidDocumentsTest.java:27)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:585)
       at junit.framework.TestCase.runTest(TestCase.java:164)
       at junit.framework.TestCase.runBare(TestCase.java:130)
       at junit.framework.TestResult$1.protect(TestResult.java:106)
       at junit.framework.TestResult.runProtected(TestResult.java:124)
       at junit.framework.TestResult.run(TestResult.java:109)
       at junit.framework.TestCase.run(TestCase.java:120)
       at junit.framework.TestSuite.runTest(TestSuite.java:230)
       at junit.framework.TestSuite.run(TestSuite.java:225)
       at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:128)
       at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
       at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
       at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
       at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
       at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
      Caused by: java.lang.ClassNotFoundException: org.hibernate.collection.PersistentMap (no security manager: RMI class loader disabled)
       at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:371)
       at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:165)
       at java.rmi.server.RMIClassLoader$2.loadClass(RMIClassLoader.java:620)
       at java.rmi.server.RMIClassLoader.loadClass(RMIClassLoader.java:247)
       at sun.rmi.server.MarshalInputStream.resolveClass(MarshalInputStream.java:197)
       at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1544)
       at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1466)
       at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1699)
       at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1305)
       at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1908)
       at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1832)
       at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1719)
       at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1305)
       at java.io.ObjectInputStream.readObject(ObjectInputStream.java:348)
       at java.util.ArrayList.readObject(ArrayList.java:591)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:585)
       at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:946)
       at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1809)
       at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1719)
       at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1305)
       at java.io.ObjectInputStream.readObject(ObjectInputStream.java:348)
       at java.rmi.MarshalledObject.get(MarshalledObject.java:135)
       at org.jboss.invocation.jrmp.interfaces.JRMPInvokerProxy.invoke(JRMPInvokerProxy.java:134)
       at org.jboss.invocation.InvokerInterceptor.invokeInvoker(InvokerInterceptor.java:365)
       at org.jboss.invocation.InvokerInterceptor.invoke(InvokerInterceptor.java:197)
       at org.jboss.proxy.TransactionInterceptor.invoke(TransactionInterceptor.java:61)
       at org.jboss.proxy.SecurityInterceptor.invoke(SecurityInterceptor.java:70)
       at org.jboss.proxy.ejb.StatelessSessionInterceptor.invoke(StatelessSessionInterceptor.java:112)
       at org.jboss.proxy.ClientContainer.invoke(ClientContainer.java:100)
       ... 20 more
      


        • 1. Re: hibernate exception not hidden from ejb client
          kukeltje

          correct, please file a jira issue for this

          • 2. Re: hibernate exception not hidden from ejb client
            gogoasa

            After some research, I found that my problem is not caused by a Hibernate specific exception that gets thrown.

            I use the GetProcessInstancesCommand in order to experiment with querying the remote ejb. This command returns a list with ProcessInstances. A ProcessInstance is read by Hibernate from the database. As Hibernate uses specific lazy-loading-aware implementations for collections -- the ProcessInstance.instances attribute, which is declared of type java.util.Map, is actually implemented by org.hibernate.collections.PersistentMap.

            Which generates class loading exception while deserializing to hibernate-unaware ejb clients.

            The solution would then be for the Command implementations to return clean JDK collections, by replacing Hibernate collection with JDK standard ones. Note that IIUC only the collections must be replaced, not the collection contents too, so the "cleaning" operation should not be that expensive.

            For people querying the SLSB remotely that should be no problem really, compared to the network marshalling cost. I wonder if other in-JVM uses of various Command's would be more sensitive performance-wise to adding some cleaning code to the standard Command implementions in jbpm-jpdl.jar.

            • 3. Re: hibernate exception not hidden from ejb client
              gogoasa

              On second thought, cleaning should be only done in the SLSB remote call use case -- because in-JVM callers may want to benefit lazy-loading...

              • 4. Re: hibernate exception not hidden from ejb client
                gogoasa