4 Replies Latest reply on Feb 13, 2002 10:51 AM by adrian.brock

    Bean Managed Stateless session Bean's Transaction Problems

    robinpaul

      hi all,

      We were using BEA Weblogic 5.1 and quite recently we decided to test our fully developed/tested Application on JBoss. Beleive me , we are having a nightmare . .

      I dont know whether it is a configuration related problem or something else

      my server's jcml files contents are shown below

      <!-- ==================================================================== -->
      <!-- Transactions -->
      <!-- ==================================================================== -->

      300
      oracle.jdbc.xa.OracleXid


      <!-- ==================================================================== -->
      <!-- JDBC -->
      <!-- ==================================================================== -->


      oracle.jdbc.driver.OracleDriver



      DefaultDS
      org.jboss.pool.jdbc.xa.wrapper.XADataSourceImpl

      jdbc:oracle:thin:@10.21.2.7:1521:sun8
      60000
      xxx
      10
      xxx
      true
      false
      false
      true
      60000
      60000
      true
      true
      1.0
      0



      I'll list down some of the observations regarding (BMT)Stateless Session Bean's Transaction Management

      case 1) (and the most deadly)
      In your business method of your bean do the following in the specified sequence
      a get a database connection
      b get a User Transaction Object from the Session Context
      c begin your transaction
      d do some inserts, updates, deletes
      e commit your transaction
      f close your connection
      Result) As observed on JBoss Server version 2.4.1 and 2.4.3
      The server doesnt commit and does not throw any exception

      case 2) (work around for case 1)
      If we do the following every thing works fine
      a. get a User Transaction Object from the Session Context
      c begin your transaction
      b. get a database connection
      d. do some inserts, updates, deletes
      e commit your transaction
      f close your connection
      Result) As observed on JBoss Server version 2.4.1 and 2.4.3
      The server commit and works as it should


      case 3) a. get a User Transaction Object from the Session Context
      b begin your transaction
      c. get a database connection
      d do some inserts, updates, deletes
      e. close your connection
      f. commit your transaction
      Result) As observed on JBoss Server version 2.4.1 and 2.4.3
      The server throws Incomplete Transaction Exception

      Stack trace on the client

      Inside Main
      ServerRef: Got the Context
      ServerRef:Looking for ejb.BMTTest
      Got Remote
      Firing method - - -
      java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
      java.rmi.RemoteException: Application error: BMT stateless bean BMTTestBean should complete transactions before returning (ejb1.1 spec, 11.6.1)
      java.rmi.RemoteException: Application error: BMT stateless bean BMTTestBean should complete transactions before returning (ejb1.1 spec, 11.6.1)
      at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:248)
      at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:223)
      at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:128)
      at org.jboss.ejb.plugins.jrmp.server.JRMPContainerInvoker_Stub.invoke(Unknown Source)
      at org.jboss.ejb.plugins.jrmp.interfaces.GenericProxy.invokeContainer(GenericProxy.java:357)
      at org.jboss.ejb.plugins.jrmp.interfaces.StatelessSessionProxy.invoke(StatelessSessionProxy.java:123)
      at $Proxy1.transactionTestMethod(Unknown Source)
      at BMTTestClient.main(BMTTestClient.java:40)
      Exception in thread "main" Interactive Session Ended



      Stack trace on the Server

      [MailService] Started
      [Service Control] Started 35 services
      [Default] JBoss 2.4.3 Started in 0m:52s
      [DefaultDS] No transaction right now.
      [DefaultDS] Pool DefaultDS [1/1/10] gave out pooled object: org.jboss.pool.jdbc.xa.wrapper.XAConnectionImpl@60a386
      [DefaultDS] java.lang.IllegalArgumentException: null xaRes
      [Default] java.lang.RuntimeException: Unable to deregister with TransactionManager: java.lang.IllegalArgumentException: null xaRes
      [Default] at org.jboss.pool.jdbc.xa.XAConnectionFactory$2.closeConnection(XAConnectionFactory.java:110)
      [Default]
      [Default] at org.jboss.pool.jdbc.xa.XAConnectionFactory$2.connectionClosed(XAConnectionFactory.java:89)
      [Default]
      [Default] at org.jboss.pool.jdbc.xa.wrapper.XAConnectionImpl.clientConnectionClosed(XAConnectionImpl.java:134)
      [Default]
      [Default] at org.jboss.pool.jdbc.xa.wrapper.XAClientConnection.close(XAClientConnection.java:250)
      [Default]
      [Default] at BMTTestBean.transactionTestMethod(BMTTestBean.java:79)
      [Default]
      [Default] at java.lang.reflect.Method.invoke(Native Method)
      [Default]
      [Default] at org.jboss.ejb.StatelessSessionContainer$ContainerInterceptor.invoke(StatelessSessionContainer.java:543)
      [Default]
      [Default] at org.jboss.ejb.plugins.TxInterceptorBMT.invoke(TxInterceptorBMT.java:276)
      [Default]
      [Default] at org.jboss.ejb.plugins.StatelessSessionInstanceInterceptor.invoke(StatelessSessionInstanceInterceptor.java:87)
      [Default]
      [Default] at org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:128)
      [Default]
      [Default] at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:195)
      [Default]
      [Default] at org.jboss.ejb.StatelessSessionContainer.invoke(StatelessSessionContainer.java:286)
      [Default]
      [Default] at org.jboss.ejb.plugins.jrmp.server.JRMPContainerInvoker.invoke(JRMPContainerInvoker.java:395)
      [Default]
      [Default] at java.lang.reflect.Method.invoke(Native Method)
      [Default]
      [Default] at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:241)
      [Default]
      [Default] at sun.rmi.transport.Transport$1.run(Transport.java:142)
      [Default]
      [Default] at java.security.AccessController.doPrivileged(Native Method)
      [Default]
      [Default] at sun.rmi.transport.Transport.serviceCall(Transport.java:139)
      [Default]
      [Default] at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:443)
      [Default]
      [Default] at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:643)
      [Default]
      [Default] at java.lang.Thread.run(Thread.java:484)
      [Default]
      [BMTTestBean] Application error: BMT stateless bean BMTTestBean should complete transactions before returning (ejb1.1 spec, 11.6.1)





      Please note that all these combinations works fine on Weblogic 5.1.0 Server. Can someone give us an explanation why it does not work for case 1 and case 3

      The sample source code is as given below

      Bean


      import javax.ejb.*;
      import javax.transaction.*;
      import java.sql.*;
      import javax.sql.*;
      import javax.naming.*;

      public class BMTTestBean implements SessionBean
      {
      private SessionContext sessionContext;
      private UserTransaction ut;
      private DataSource ds;

      public void ejbCreate() throws CreateException
      {
      }

      public void ejbRemove()
      {
      }

      public void ejbActivate()
      {
      }

      public void ejbPassivate()
      {
      }

      public void setSessionContext(SessionContext context)
      {
      sessionContext = context;
      }

      public void transactionTestMethod()
      {
      Connection con = null;
      PreparedStatement stmt = null;

      StringBuffer sbf1 = new StringBuffer("Insert into test_table( id, name) values (1,'Robin Paul')");
      StringBuffer sbf2 = new StringBuffer("Insert into test_table( id, name) values (2,'Jikky John')");
      try
      {

      con = getConnection();
      ut = sessionContext.getUserTransaction();
      ut.begin();
      stmt = con.prepareStatement(sbf1.toString());
      sbf1 = null;
      stmt.executeUpdate();
      stmt.close();
      stmt = con.prepareStatement(sbf2.toString());
      sbf2 = null;
      stmt.executeUpdate();
      ut.commit();
      }
      catch( Exception se )
      {
      se.printStackTrace();
      try
      {
      ut.rollback();
      }
      catch( Exception e)
      {
      e.printStackTrace();
      }
      }
      finally
      {
      try
      {
      if( stmt != null )
      {
      stmt.close();
      }
      if( con != null )
      {
      con.close();
      }
      }
      catch( SQLException se)
      {
      se.printStackTrace();
      }
      }
      }

      private Connection getConnection() throws Exception
      {
      InitialContext initCtx = null;
      initCtx = new InitialContext();
      ds = (javax.sql.DataSource) initCtx.lookup("java:comp/env/jdbc/oraclePool");
      initCtx.close();
      return ds.getConnection();
      }


      }


      *************************** Home ******************
      import javax.ejb.EJBHome;
      import javax.ejb.CreateException;
      import java.rmi.RemoteException;


      public interface BMTTestHome extends EJBHome
      {
      public BMTTest create() throws CreateException, RemoteException;
      }


      ******************** Remote *****************************
      import javax.ejb.EJBObject;
      import javax.ejb.CreateException;
      import java.rmi.RemoteException;


      public interface BMTTest extends EJBObject
      {
      public void transactionTestMethod() throws RemoteException;
      }

      *********************** ejb -jar.xml *****************************

      <?xml version="1.0" encoding="Cp1252"?>
      <!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN' 'http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd'>
      <ejb-jar>
      <enterprise-beans>

      <ejb-name>BMTTestBean</ejb-name>
      BMTTestHome
      BMTTest
      <ejb-class>BMTTestBean</ejb-class>
      <session-type>Stateless</session-type>
      <transaction-type>Bean</transaction-type>
      <resource-ref>
      <res-ref-name>jdbc/oraclePool</res-ref-name>
      <res-type>javax.sql.DataSource</res-type>
      <res-auth>Container</res-auth>
      </resource-ref>

      </enterprise-beans>
      </ejb-jar>

      ******************************jboss.xml***************************
      <?xml version="1.0" encoding="UTF-8"?>

      <enterprise-beans>

      <ejb-name>BMTTestBean</ejb-name>
      <jndi-name>ejb.BMTTest</jndi-name>
      <reference-descriptor>
      <resource-description>
      <res-ref-name>jdbc/oraclePool</res-ref-name>
      <jndi-name>java:/DefaultDS</jndi-name>
      </resource-description>
      </reference-descriptor>

      </enterprise-beans>



      *********************Client.java*************************************

      import java.util.*;
      import javax.ejb.*;
      import javax.naming.*;
      import java.rmi.*;
      import java.util.*;
      import javax.rmi.PortableRemoteObject;


      public class BMTTestClient
      {
      public static Object getServerRef(String JNDIName)
      {
      Object serverRef = null;
      try
      {
      Properties h = new Properties();
      h.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory" );
      h.put(Context.PROVIDER_URL,"10.21.13.5:1099");
      InitialContext ctx = new InitialContext(h);
      System.out.println("ServerRef: Got the Context");
      System.out.println("ServerRef:Looking for " + JNDIName);
      serverRef = ctx.lookup(JNDIName);
      }
      catch(NamingException e)
      {
      e.printStackTrace();
      }
      return serverRef;
      }

      public static void main( String args[] ) throws Exception
      {
      System.out.println("Inside Main");
      Object beanRef = getServerRef( "ejb.BMTTest" );
      BMTTestHome beanHome = (BMTTestHome)PortableRemoteObject.narrow(beanRef, BMTTestHome.class);
      BMTTest beanRemote = beanHome.create();
      System.out.println("Got Remote");
      System.out.println("Firing method - - - ");
      beanRemote.transactionTestMethod();
      System.out.println("success");
      }
      }




      Thanks and Regards

      Robin Paul