2 Replies Latest reply on Jun 24, 2009 11:47 AM by rubenvdg

    SessionContext not injected when using scoped class loaders

      Summary: When I configure the ear-deployer with "isolated=true" to have scoped class loading for each EAR, the session context is not injected (through @Resource) in my stateless session bean. When I switch isolated class loading off, the session context is injected. I package a more recent Hibernate version in the EAR. (so, the configuration of "isolated" does have an effect on the hibernate version used.)

      More elaborate version:

      I use JBoss 4.2.3.GA, running on Sun Java "1.6.0_14", on Linux amd64. The JBoss version is the version compiled for JDK5, but running on JDK6, with some libraries copied from the "client" dir to the "lib/endorsed" dir as mentioned in the release notes.

      We want to standardize on a specific Hibernate version, independently of the Hibernate version that comes with JBoss. For this reason, we build our ear with the Hibernate libraries included. We use the following maven dependencies for Hibernate.

      <dependency>
       <groupId>org.hibernate</groupId>
       <artifactId>hibernate-validator</artifactId>
       <version>3.0.0.ga</version>
       </dependency>
       <dependency>
       <groupId>org.hibernate</groupId>
       <artifactId>hibernate-search</artifactId>
       <version>3.0.0.GA</version>
       <exclusions>
       <exclusion>
       <groupId>org.hibernate</groupId>
       <artifactId>ejb3-persistence</artifactId>
       </exclusion>
       </exclusions>
       </dependency>
       <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>
       <version>1.5.6</version>
       </dependency>
       <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-log4j12</artifactId>
       <version>1.5.6</version>
       </dependency>
      


      We also configured Hibernate to use "cglib" instead of "javassist". (We got VerifyErrors because of final methods when we used "javassist".) This is configured in the file deploy/ejb3.deployer/META-INF/persistence.properties.

      hibernate.bytecode.provider=cglib


      To make sure that "our" version of the Hibernate libraries gets loaded, we configure the ear-deployer and set the isolated property on "true". This, as far as I understand it, means that when our application wants to load a class, the class loader will first search the EAR for the required class, and if it is not found in there, it will search the class in the libraries that come with the application server. It also means that classes loaded by EAR1 cannot be seen by EAR2. This is the behaviour that we want, independently of the Hibernate issue.

      The framework code that we use (and have written), is available on ppwcode. The implementation of the session bean where I have the problem, is a subclass of the following abstract class JpaStatelessCrudDao. This is a generic class that implements CRUD operations on any entity (PersistentBean). For the implementation of security, we implemented a couple of annotations. These annotations are placed on the entity class and define which JAAS roles can create, update and delete entities of that type. In a subclass of JpaStatelessCrudDao, you need to implement the following abstract method.

      protected abstract boolean isCallerInRole(String role);


      We use a subclass of JpaStatelessCrudDao that is a stateless session bean. In that context, the implementation of "isCallerInRole" is as follows.

      @Override
       protected boolean isCallerInRole(String role) {
       return getSessionContext().isCallerInRole(role);
       }


      The session context is injected, and the relevant code is the following.

      public final SessionContext getSessionContext() {
       return $sessionContext;
       }
      
       public final void setSessionContext(SessionContext sessionContext) {
       $sessionContext = sessionContext;
       }
      
       @Resource
       private SessionContext $sessionContext;


      When I run this code on JBoss 4.2.3.GA and call methods on the session bean (subclass of JpaStatelessCrudDao), I get a NullPointerException because the session context is null.

      The stacktrace looks as the following:

      javax.ejb.EJBException: java.lang.NullPointerException
       at org.jboss.ejb3.tx.Ejb3TxPolicy.handleExceptionInOurTx(Ejb3TxPolicy.java:63)
       at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:83)
       at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:191)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:95)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:62)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:77)
       at org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3AuthenticationInterceptor.java:110)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:46)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.stateless.StatelessContainer.dynamicInvoke(StatelessContainer.java:304)
       at org.jboss.ejb3.remoting.IsLocalInterceptor.invokeLocal(IsLocalInterceptor.java:81)
       at org.jboss.ejb3.remoting.IsLocalInterceptor.invoke(IsLocalInterceptor.java:72)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.stateless.StatelessRemoteProxy.invoke(StatelessRemoteProxy.java:107)
       at $Proxy126.createPersistentBean(Unknown Source)
       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:597)
       at org.directwebremoting.impl.ExecuteAjaxFilter.doFilter(ExecuteAjaxFilter.java:34)
       at org.directwebremoting.impl.DefaultRemoter$1.doFilter(DefaultRemoter.java:428)
       at org.directwebremoting.impl.DefaultRemoter.execute(DefaultRemoter.java:431)
       at org.directwebremoting.impl.DefaultRemoter.execute(DefaultRemoter.java:283)
       at org.directwebremoting.servlet.PlainCallHandler.handle(PlainCallHandler.java:52)
       at org.directwebremoting.servlet.UrlProcessor.handle(UrlProcessor.java:101)
       at org.directwebremoting.servlet.DwrServlet.doPost(DwrServlet.java:146)
       at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
       at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
       at org.ppwcode.vernacular.l10n_III.web.HttpRequestLocaleFilter.doRequestLocaleFilter(HttpRequestLocaleFilter.java:110)
       at org.ppwcode.vernacular.l10n_III.web.HttpRequestLocaleFilter.doFilter(HttpRequestLocaleFilter.java:71)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
       at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
       at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
       at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
       at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:182)
       at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
       at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
       at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
       at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)
       at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
       at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:262)
       at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
       at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
       at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:446)
       at java.lang.Thread.run(Thread.java:619)
      Caused by: java.lang.NullPointerException
       at xxxxx.businesslogic.jpa.JpaStatelessCrudDao.isCallerInRole(JpaStatelessCrudDao.java:105)
       at org.ppwcode.vernacular.persistence_III.dao.jpa.JpaStatelessCrudDao.callerInAtLeastOneOfRoles(JpaStatelessCrudDao.java:705)
       at org.ppwcode.vernacular.persistence_III.dao.jpa.JpaStatelessCrudDao.isCreateAllowed(JpaStatelessCrudDao.java:637)
       at org.ppwcode.vernacular.persistence_III.dao.jpa.JpaStatelessCrudDao.createPersistentBean(JpaStatelessCrudDao.java:382)
       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:597)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:112)
       at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:166)
       at org.jboss.ejb3.interceptor.EJB3InterceptorsInterceptor.invoke(EJB3InterceptorsInterceptor.java:63)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:54)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:47)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:79)
      


      What happens here is the following. We have an EJB3 backend that runs in an EAR on the JBoss server. We also have a frontend running on the same JBoss server that is built with Dojo and DWR. I try to create an entity through the frontend.

      When we switch the isolated property in the ear-deployer back to "false", the session context is injected and the application behaves as intended.

      Is this a bug, or are we doing something wrong?

        • 1. Re: SessionContext not injected when using scoped class load
          jaikiran

          Looking at the forum threads, you are not the first one to complain about this http://www.jboss.org/index.html?module=bb&op=viewtopic&t=151427 So i guess, there's definitely some issue here. I have tried to reproduce this locally but haven't been successful yet. Could you please look at that other thread and provide the similar details i asked for.

          Also, could you try reproducing this against JBossAS-5.1.0?

          • 2. Re: SessionContext not injected when using scoped class load

            I checked the list of included classes in the ear.

            rvdginste@odalix:/tmp/test$ for i in `ls *.jar` ; do echo $i ; jar tf $i | grep 'javax.annotation' ; jar tf $i | grep 'javax.ejb' ; done
            xxxxx-ejbs-dev-SNAPSHOT.jar
            Toryt-annotations-I-2.0.jar
            antlr-2.7.6.jar
            aopalliance-1.0.jar
            asm-1.5.3.jar
            asm-attrs-1.5.3.jar
            cglib-2.1_3.jar
            commons-beanutils-1.7.0.jar
            commons-beanutils-core-1.7.0.jar
            commons-collections-3.2.jar
            commons-lang-2.0.jar
            commons-logging-1.1.1.jar
            dom4j-1.6.1.jar
            dwr-2.0.3.jar
            ehcache-1.2.3.jar
            ezmorph-1.0.4.jar
            hibernate-3.2.6.ga.jar
            hibernate-annotations-3.3.1.GA.jar
            hibernate-commons-annotations-3.0.0.ga.jar
            hibernate-entitymanager-3.3.2.GA.jar
            hibernate-search-3.0.0.GA.jar
            hibernate-validator-3.0.0.ga.jar
            javassist-3.4.GA.jar
            json-lib-2.2.2-jdk15.jar
            jsr250-api-1.0.jar
            javax/annotation/
            javax/annotation/security/
            javax/annotation/Generated.class
            javax/annotation/PostConstruct.class
            javax/annotation/PreDestroy.class
            javax/annotation/Resource$AuthenticationType.class
            javax/annotation/Resource.class
            javax/annotation/Resources.class
            javax/annotation/security/DeclareRoles.class
            javax/annotation/security/DenyAll.class
            javax/annotation/security/PermitAll.class
            javax/annotation/security/RolesAllowed.class
            javax/annotation/security/RunAs.class
            log4j-1.2.14.jar
            lucene-core-2.2.0.jar
            ppwcode-metainfo-I-2.1.jar
            ppwcode-util-exception-III-1.0.jar
            ppwcode-util-reflection-I-1.0.jar
            ppwcode-util-serialization-I-1.0.jar
            ppwcode-value-III-dev-SNAPSHOT.jar
            ppwcode-vernacular-exception-III-2.0-SNAPSHOT.jar
            ppwcode-vernacular-l10n-III-1.1-SNAPSHOT.jar
            ppwcode-vernacular-persistence-III-1.0.0-SNAPSHOT.jar
            ppwcode-vernacular-resourcebundle-II-1.4.jar
            ppwcode-vernacular-semantics-VI-2.0-SNAPSHOT.jar
            ppwcode-vernacular-value-III-2.1-SNAPSHOT.jar
            slf4j-api-1.5.6.jar
            slf4j-log4j12-1.5.6.jar
            spring-beans-2.5.jar
            spring-context-2.5.jar
            spring-core-2.5.6.jar
            spring-jdbc-2.5.jar
            spring-test-2.5.6.jar
            spring-tx-2.5.jar
            


            As you can see, the @Resource annotation is included in the ear, and taking into account the "isolated=true" setting, this explains why the session context wasn't injected.

            Thanks a bunch!