4 Replies Latest reply on May 6, 2008 3:25 AM by lucas montes

    transaction exception while jndi lookup

    lucas montes Newbie

      hello,

      I will try to expose my situation in details :

      I'm working on a project using jboss-portal.

      i've got an ear archive deployed which contains portlets for jboss portal, and a lot of entity beans mapped with JPA.

      I'm trying to reimplement portal Identity API (HibernateUserModule, HibernateUserProfileModule, etc...) to map users and roles in my custom database. So i've done a jar file containing my implementation of this modules. this jar isn't in my main ear package where entity beans are, but is deployed in the lib dir of jboss-portal.sar.

      So the thing i'm trying to do is :

      - from my implementation of HibernateUserModule (in the jar contained in lib dir of portal), i'm trying to access an ejb session from my ear package via jndi lookup. ((NameOfEJBLocalInterface) new InitialContext().lookup('/myproj-ear/NameOfEJB/local') ). my implementation is only extending the original HibernateUserModule for testing purpose. I have just overrided a fonction where i do the jndi lookup.(findUserByUserName). I've modified correctly the identity-config file of portal for it to use my implementation.

      - I verified in the jboss jmx console that my ejb session is correctly mapped in the jndi context, and it is in the global jndi namespace under myproj-ear/NameOfEJB/local.

      additional infos :
      JBoss version : 4.2.0 GA
      Portal version : 2.6.4 GA
      EJB3

      now here comes my problem: :)
      i got this exception at the execution of the lookup :
      java.lang.IllegalStateException: Wrong tx on thread: expected TransactionImple < ac, BasicAction: -3f57fe93:cf77:4816ea73:38b status: ActionStatus.ABORT_ONLY >, actual TransactionImple < ac, BasicAction: -3f57fe93:cf77:4816ea73:395 status: ActionStatus.RUNNING >
      at org.jboss.aspects.tx.TxPolicy.endTransaction(TxPolicy.java:162)
      at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:87)
      at org.jboss.aspects.tx.TxInterceptor$RequiresNew.invoke(TxInterceptor.java:262)
      at org.jboss.portal.core.aspects.server.TransactionInterceptor$invoke_N5143606530999904530.invokeNext(TransactionInterceptor$invoke_N5143606530999904530.java)
      at org.jboss.portal.core.aspects.server.TransactionInterceptor.invoke(TransactionInterceptor.java)
      at org.jboss.portal.server.ServerInterceptor.invoke(ServerInterceptor.java:38)
      at org.jboss.portal.common.invocation.Invocation.invokeNext(Invocation.java:115)
      at org.jboss.portal.server.aspects.LockInterceptor$InternalLock.invoke(LockInterceptor.java:69)
      at org.jboss.portal.server.aspects.LockInterceptor.invoke(LockInterceptor.java:130)
      at org.jboss.portal.common.invocation.Invocation.invokeNext(Invocation.java:115)
      at org.jboss.portal.common.invocation.Invocation.invoke(Invocation.java:157)
      at org.jboss.portal.server.servlet.PortalServlet.service(PortalServlet.java:250)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)


      i tested that with different semantics with intentional mistakes in the jndiName, and i got "namingException : myMistakeName not bound".

      so i figure it means i'm doing the lookup in the good way, but it seems to be a problem of transaction management (ie: the exception).

      The bean extending HibernateUserModule in my jar is a POJO, so i think i'll have to deal with transaction management myself. (but i don't really know about this subject). I will continue my investigations but any clues would be really appreciable :)

      Regards,

      --
      Lucas
      Montes

      ps: if you need some other information on the project i'll answer with pleasure :)

        • 1. Re: transaction exception while jndi lookup
          lucas montes Newbie

          i've done some tests they might be helpfull to resolve this issue.

          i've changed the instruction :
          obj = (NameOfEJBLocalInterface) new InitialContext().lookup(jndiName);

          to :
          Object obj = new InitialContext().lookup(jndiName);
          System.out.println(obj.toString());
          NameOfEJBLocalInterface obj2 = (NameOfEJBLocalInterface) obj;

          now the "wrong tx" exception is happening on the "cast" line (the last one)...

          the jndi lookup works fine and i've got this output from the obj.toString instruction : IdentityUserModule:5c4o0f-y2rqf0-ffmxpqgv-1-ffmxtfx0-dbla

          i must be doing something wrong. I'd like to add that my ear project uses Jboss-seam 2.0.0GA, and here's the code of my session EJB in the ear package :

          import javax.ejb.Stateful;
          
          import com.smalltox.business.model.persistent.impl.site.SiteAccountImpl;
          
          @Stateful
          
          public class IdentityUserModule implements IdentityUserModuleLocalInterface {
          
           public SiteAccountImpl findUserByUserName(String userName) {
           //some code that uses entities to query my own database (not portal's)
           }
          }
          


          and now the interface :

          import javax.ejb.Local;
          
          import com.smalltox.business.model.persistent.impl.site.SiteAccountImpl;
          
          @Local
          public interface IdentityUserModuleLocalInterface {
           public SiteAccountImpl findUserByUserName(String userName);
          }
          


          maybe it has something to do with the fact that the sources of my ear are in my eclipse build path but it's not present in the JAR i put in portal libdir.

          any clues would be really appreciated ;)

          Regards,

          --
          Lucas
          Montes

          • 2. Re: transaction exception while jndi lookup
            lucas montes Newbie

            i finally got rid of the Wrong tx on thread, but another strange issue is happening :

            I first get the TransactionManager via jndi (java:TransactionManager).

            then i suspend the current transaction :
            t = tm.suspend();

            then i do the lookup of my EJB remote or local interface, and i put it into an JBossProxy interface.

            then i print infos with the getClass() method :

            
            tmp = (JBossProxy) new InitialContext().lookup("smalltox-ear/IdentityUserModule/remote");
             System.out.println("obj : " + tmp.getClass().getName() + " " + tmp.getClass().getSimpleName() + " " + tmp.getClass().getSuperclass() + " " + tmp.getClass().getPackage() );
            
            
             for (int i = 0; i < tmp.getClass().getMethods().length; i++) {
             System.out.println("method : " + tmp.getClass().getMethods()
            .getName());
             }
            
            
             for (int i = 0; i < tmp.getClass().getInterfaces().length; i++)
             System.out.println("Interface : " + tmp.getClass().getInterfaces()
            .getName());
            
            
            






            and here's the output :

            
            obj : $Proxy855 $Proxy855 class java.lang.reflect.Proxy null
            
            10:20:29,339 INFO [STDOUT] method : hashCode
            10:20:29,339 INFO [STDOUT] method : equals
            10:20:29,339 INFO [STDOUT] method : toString
            10:20:29,339 INFO [STDOUT] method : findUserByUserName
            10:20:29,340 INFO [STDOUT] method : getAsynchronousProxy
            10:20:29,340 INFO [STDOUT] method : isProxyClass
            10:20:29,340 INFO [STDOUT] method : getProxyClass
            10:20:29,340 INFO [STDOUT] method : newProxyInstance
            10:20:29,340 INFO [STDOUT] method : getInvocationHandler
            10:20:29,340 INFO [STDOUT] method : wait
            10:20:29,340 INFO [STDOUT] method : wait
            10:20:29,340 INFO [STDOUT] method : wait
            10:20:29,340 INFO [STDOUT] method : getClass
            10:20:29,340 INFO [STDOUT] method : notify
            10:20:29,340 INFO [STDOUT] method : notifyAll
            
            10:20:29,340 INFO [STDOUT] Interface : com.smalltox.foundation.identity.IdentityUserModuleRemote
            10:20:29,341 INFO [STDOUT] Interface : org.jboss.ejb3.JBossProxy
            
            



            then i try to cast the JBossProxy object into my local or remote interface and i got a class cast exception :

            $Proxy855 cannot be cast to com.smalltox.foundation.identity.IdentityUserModuleRemote

            this is really strange, and the samething happen whether i resume the transaction before the cast of after..

            the encouraging part is that portal continues to work well after i resume the transaction.

            i'd like to add that in my jmx console, i've got this output in the JNDIView :

            
            when remote + ejb stateful
            Global JNDI Namespace
            
            +- smalltox-ear (class: org.jnp.interfaces.NamingContext)
             +- IdentityUserModule (class: org.jnp.interfaces.NamingContext)
             | | +- remote (class: java.lang.Object)
             | | +- remoteStatefulProxyFactory (proxy: $Proxy857 implements interface org.jboss.ejb3.Pr
            oxyFactory)
            
            when remote and ejb statless
            
            +- smalltox-ear (class: org.jnp.interfaces.NamingContext)
             +- IdentityUserModule (class: org.jnp.interfaces.NamingContext)
             | | +- remote (proxy: $Proxy854 implements interface com.smalltox.foundation.identity.Iden
            tityUserModuleRemote,interface org.jboss.ejb3.JBossProxy)
            
            
            when i make my EJB local and stateless:
            
            +- smalltox-ear (class: org.jnp.interfaces.NamingContext)
             +- IdentityUserModule (class: org.jnp.interfaces.NamingContext)
             | | +- local (proxy: $proxy855 implements interface com.smalltox.foundation.identity.Ident
            ityUserModuleLocalInterface, interface org.jboss.ejb3.JBossProxy)
            
            
            



            i think it migth be caused by the fact my local or remote interfaces are in a jar in the libdir of portal, and also in my ear. but i can't see any other way of calling my ejb from the portal app.

            any clues would help a lot,

            Regards,

            --
            Lucas
            Montes



            • 3. Re: transaction exception while jndi lookup
              lucas montes Newbie

              so the problem is caused by the isolation of classloading in my ear.

              I tested by putting the attribute calledByValue in default/deploy/conf/jboss-service.xml and it worked, but it's not an acceptable solution as it has repercutions on all jndi lookups, and it increase a lot the ressource usage of such operations.

              that's why i'd like to know how to force the calledbyvalue on an EJB3 lookup (and only on one EJB)

              i'm searching a lot by myself, (maybe not the right way :), but any clues or link to a corresponding documentation would really help me. (i found some docs but all ejb2 / jboss < 4.2.2.GA related... i don"t has enought knowledge of EJB's to adapt those solution by myself (for now :)

              thanks,

              --
              Lucas
              Montes

              • 4. Re: transaction exception while jndi lookup
                lucas montes Newbie

                problem solved :) i've done a lookup forcing the marshalling for method invocation (called-by-value) by putting the full scheme in the lookup :

                new InitialContext("jnp://localhost:1099/EJBJndiName");
                


                (my project manager wanted to keep the scoping of classloading for my ear so that was the less ugly way to do it :)