6 Replies Latest reply on Feb 28, 2002 1:15 AM by ggreaves

    UndeclaredThrowableException from Container Invoked Callback

    cm

      I've looked at previous posts dealing with the UndeclaredThrowableException and found one post that seemed similiar to my situation with no response and a few other posts that dealt with an earlier version of JBoss. I am using JBoss 2.2.1 and I've noticed that if an EJBException is thrown from the ejbStore of a bean managed entity bean, then the client receives a java.lang.reflect.UndeclaredThrowableException instead of a RemoteException. It seems like the EJB Spec specifies that a RemoteException should be received by the client.

      In order to define an exception handling scheme for my EJB components and understand how exceptions work with EJBs I tried the following:
      A client test program calls a session bean named PartyManager that updates a bean managed entity bean named Party. Within the ejbStore method of the Party entity bean, a SQLException is thrown (because the SQL statement's syntax is incorrect). The SQLException is caught and then an EJBException is thrown. The ejbStore method looks as follows:

      public void ejbStore()
      {
      // Create our database objects
      Connection conn = null;
      PreparedStatement ps = null;

      try
      {
      // Create an UPDATE prepared statement
      conn = DbUtils.getConnection();
      ps = conn.prepareStatement( SQL_UPDATE_QUERY );

      ps.setString( 1, this.guid );
      ps.setString( 2, this.name );


      // Execute the Update
      if( ps.executeUpdate() != 1 )
      {
      throw new EJBException( "ejbStore failed updating party with primary key: " + this.id.longValue() );
      }

      }
      catch( SQLException eSQL )
      {
      EJBException e = new EJBException( eSQL );
      throw e;
      }
      finally
      {
      try
      {
      // Clean up our database objects
      if( ps != null ) ps.close();
      if( conn != null ) conn.close();
      }
      catch( SQLException eSQL )
      {
      eSQL.printStackTrace();
      }
      }
      }

      The server.log contains the following stacktrace:

      [PartyManagerBean] java.sql.SQLException: ORA-00900: invalid SQL statement
      [PartyManagerBean] at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:114)
      [PartyManagerBean] at oracle.jdbc.oci8.OCIDBAccess.check_error(OCIDBAccess.java:1503)
      [PartyManagerBean] at oracle.jdbc.oci8.OCIDBAccess.executeFetch(OCIDBAccess.java:1111)
      [PartyManagerBean] at oracle.jdbc.oci8.OCIDBAccess.parseExecuteFetch(OCIDBAccess.java:1235)
      [PartyManagerBean] at oracle.jdbc.driver.OracleStatement.executeNonQuery(OracleStatement.java:1313)
      [PartyManagerBean] at oracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.java:1232)
      [PartyManagerBean] at oracle.jdbc.driver.OracleStatement.doExecuteWithBatch(OracleStatement.java:1353)
      [PartyManagerBean] at oracle.jdbc.driver.OracleStatement.doExecute(OracleStatement.java:1760)
      [PartyManagerBean] at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1805)
      [PartyManagerBean] at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:322)
      [PartyManagerBean] at org.opentools.minerva.jdbc.PreparedStatementInPool.executeUpdate(PreparedStatementInPool.java:82)
      [PartyManagerBean] at com.ipnetsolutions.config.srv.party.PartyBean.ejbStore(PartyBean.java:1552)
      [PartyManagerBean] at java.lang.reflect.Method.invoke(Native Method)
      [PartyManagerBean] at org.jboss.ejb.plugins.BMPPersistenceManager.storeEntity(BMPPersistenceManager.java:331)
      [PartyManagerBean] at org.jboss.ejb.plugins.EntitySynchronizationInterceptor$InstanceSynchronization.beforeCompletion(EntitySynchronizationInterceptor.java:342)
      [PartyManagerBean] at org.jboss.tm.TxCapsule.doBeforeCompletion(TxCapsule.java:1228)
      [PartyManagerBean] at org.jboss.tm.TxCapsule.commit(TxCapsule.java:322)
      [PartyManagerBean] at org.jboss.tm.TransactionImpl.commit(TransactionImpl.java:76)
      [PartyManagerBean] at org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:318)
      [PartyManagerBean] at org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:99)
      [PartyManagerBean] at org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:190)
      [PartyManagerBean] at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:195)
      [PartyManagerBean] at org.jboss.ejb.StatelessSessionContainer.invoke(StatelessSessionContainer.java:271)
      [PartyManagerBean] at org.jboss.ejb.plugins.jrmp.server.JRMPContainerInvoker.invoke(JRMPContainerInvoker.java:392)
      [PartyManagerBean] at java.lang.reflect.Method.invoke(Native Method)
      [PartyManagerBean] at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:241)
      [PartyManagerBean] at sun.rmi.transport.Transport$1.run(Transport.java:142)
      [PartyManagerBean] at java.security.AccessController.doPrivileged(Native Method)
      [PartyManagerBean] at sun.rmi.transport.Transport.serviceCall(Transport.java:139)
      [PartyManagerBean] at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:443)
      [PartyManagerBean] at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:643)
      [PartyManagerBean] at java.lang.Thread.run(Thread.java:484)

      [PartyManagerBean] javax.ejb.EJBException
      [PartyManagerBean] at com.ipnetsolutions.config.srv.party.PartyBean.ejbStore(PartyBean.java:1566)
      [PartyManagerBean] at java.lang.reflect.Method.invoke(Native Method)
      [PartyManagerBean] at org.jboss.ejb.plugins.BMPPersistenceManager.storeEntity(BMPPersistenceManager.java:331)
      [PartyManagerBean] at org.jboss.ejb.plugins.EntitySynchronizationInterceptor$InstanceSynchronization.beforeCompletion(EntitySynchronizationInterceptor.java:342)
      [PartyManagerBean] at org.jboss.tm.TxCapsule.doBeforeCompletion(TxCapsule.java:1228)
      [PartyManagerBean] at org.jboss.tm.TxCapsule.commit(TxCapsule.java:322)
      [PartyManagerBean] at org.jboss.tm.TransactionImpl.commit(TransactionImpl.java:76)
      [PartyManagerBean] at org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:318)
      [PartyManagerBean] at org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:99)
      [PartyManagerBean] at org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:190)
      [PartyManagerBean] at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:195)
      [PartyManagerBean] at org.jboss.ejb.StatelessSessionContainer.invoke(StatelessSessionContainer.java:271)
      [PartyManagerBean] at org.jboss.ejb.plugins.jrmp.server.JRMPContainerInvoker.invoke(JRMPContainerInvoker.java:392)
      [PartyManagerBean] at java.lang.reflect.Method.invoke(Native Method)
      [PartyManagerBean] at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:241)
      [PartyManagerBean] at sun.rmi.transport.Transport$1.run(Transport.java:142)
      [PartyManagerBean] at java.security.AccessController.doPrivileged(Native Method)
      [PartyManagerBean] at sun.rmi.transport.Transport.serviceCall(Transport.java:139)
      [PartyManagerBean] at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:443)
      [PartyManagerBean] at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:643)
      [PartyManagerBean] at java.lang.Thread.run(Thread.java:484)

      When the client gets the exception, the client gets a java.lang.reflect.UndeclaredThrowableException instead of a RemoteException. I think the client is getting the UndeclaredThrowableException, because the container is throwing a javax.transaction.RollbackException (which extends from Exception) as opposed to the javax.transaction.TransactionRollbackException (which extends from java.rmi.RemoteException). The client's stacktrace is as follows:

      java.lang.reflect.UndeclaredThrowableException: javax.transaction.RollbackException: Unable to commit, tx=XidImpl [FormatId=257, GlobalId=shaines2//3, BranchQual=] status=STATUS_ROLLEDBACK
      at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:245)
      at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:220)
      at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:122)
      at org.jboss.ejb.plugins.jrmp.server.JRMPContainerInvoker_Stub.invoke(Unknown Source)
      at org.jboss.ejb.plugins.jrmp.interfaces.StatelessSessionProxy.invoke(StatelessSessionProxy.java:188)
      at $Proxy1.update(Unknown Source)
      at com.ipnetsolutions.config.itf.EJBConfigurator.updateParty(EJBConfigurator.java:2531)
      at TestClient.testEJBException(TestClient.java:1517)
      at TestClient.main(TestClient.java:96)

      If I try a different experiment and cause an EJBException within a stateless session bean, then the client DOES receive a RemoteException. Should a RemoteException be received by the client when an EJBException is thrown from a container invoked callback? Is there a problem with JBoss?

      Thanks in advance for any help.