6 Replies Latest reply on May 6, 2008 3:30 AM by loucs

    problem while implementing portal identity API with a jndi l

    loucs

      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: problem while implementing portal identity API with a jn
          loucs

          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: problem while implementing portal identity API with a jn
            loucs

            with the stack trace, it seems to come from portal interceptors... i don't have the time to watch portal source code in detail so if someone from the portal crew has any clue ;)

            • 3. Re: problem while implementing portal identity API with a jn
              loucs

              i've done the same thing accessing my ejb with jmx and the same exception happened. i'm must make a mistake deploying my ear in portal...

              here's the code i used instead og the jndi lookup (i've made a local interface for my ejb with the @Local annotation) :

              
              MBeanServer mbeanServer = MBeanServerLocator.locateJBoss();
              userModule = (IdentityUserModuleLocalInterface) MBeanProxy.get(IdentityUserModuleLocalInterface.class, new ObjectName(""), mbeanServer);
              
              


              Regards,

              --
              Lucas
              Montes

              • 4. Re: problem while implementing portal identity API with a jn
                loucs

                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



                • 5. Re: problem while implementing portal identity API with a jn
                  loucs

                  Ok, so i went forward throught this problem and it's caused by the fact my ear project uses Richfaces (3.2.0.GA) with seam (2.0.0.GA) in portlets. It work perfectlly well but the ear project had to be isolated, with the creation of a loader-repository for my ear. this prevent me to cast the proxy object i get from a jndi lookup outside of my ear in the local or remote interface of my ejb.

                  i have two solution : i can search for a way to make richfaces work without having to isolate the ear classloading (wich i'm doing looking at the richfaces + portal discussion (with the portletbridge, but i don't think it works differently ), or i can force the EJB to be called by value, but all the docs i find on the subject are about ejb 2.0 and older versions of JBoss (i'm using 4.2.2.GA).

                  I tested this last one 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), or if possible a solution allowing not to isolate classloading in my ear.

                  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.

                  thanks,

                  --
                  Lucas
                  Montes

                  • 6. Re: problem while implementing portal identity API with a jn
                    loucs

                    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 :)