glassfish
  1. glassfish
  2. GLASSFISH-19581

Random regression: @Resource DataSource injection is not working when CDI is enabled

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Critical Critical
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: cdi
    • Labels:
      None

      Description

      See e.g. http://hudson-sca.us.oracle.com/job/ejb-devtests-trunk/1905/

      The failing test is ejb31/full/jcdifull (but Hong noticed that you might need to run all tests under ejb31/full to reproduce the error condition).

      From the console output:

      deploy-jar-common:
      [exec] asadmin --host localhost --port 60836 --user anonymous --passwordfile <http://hudson-sca.us.oracle.com/job/ejb-devtests-trunk/ws/appserv-tests/config/adminpassword.txt> --interactive=false --echo=true --terse=true deploy --force=false --precompilejsp=false --verify=false --generatermistubs=false --availabilityenabled=false --asyncreplication=true --target server --keepreposdir=false --keepfailedstubs=false --isredeploy=false --logreportederrors=true --_classicstyle=false --upload=true <http://hudson-sca.us.oracle.com/job/ejb-devtests-trunk/ws/appserv-tests/build/module/archive/ejb-ejb31-full-jcdifull-ejb.jar>
      [exec] remote failure: Error occurred during deployment: Exception while loading the app : javax.ejb.CreateException: Initialization failed for Singleton SingletonBeanA. Please see server.log for more details.

      And in server.log:
      Caused by: org.jboss.weld.exceptions.WeldException: WELD-000049 Unable to invoke [method] @PostConstruct public com.acme.Bar.init() on Bar
      at org.jboss.weld.bean.AbstractClassBean.defaultPostConstruct(AbstractClassBean.java:404)
      at org.jboss.weld.bean.ManagedBean$ManagedBeanInjectionTarget.postConstruct(ManagedBean.java:174)
      at org.jboss.weld.bean.ManagedBean.create(ManagedBean.java:294)
      at org.jboss.weld.context.unbound.DependentContextImpl.get(DependentContextImpl.java:68)
      at org.jboss.weld.manager.BeanManagerImpl.getReference(BeanManagerImpl.java:608)
      at org.jboss.weld.manager.BeanManagerImpl.getReference(BeanManagerImpl.java:674)
      at org.jboss.weld.injection.ParameterInjectionPoint.getValueToInject(ParameterInjectionPoint.java:120)
      at org.jboss.weld.injection.ConstructorInjectionPoint.getParameterValues(ConstructorInjectionPoint.java:170)
      at org.jboss.weld.injection.ConstructorInjectionPoint.newInstance(ConstructorInjectionPoint.java:117)
      at org.jboss.weld.bean.SessionBean.createInstance(SessionBean.java:213)
      at org.jboss.weld.bean.SessionBean$SessionBeanInjectionTarget.produce(SessionBean.java:202)
      at org.glassfish.weld.services.JCDIServiceImpl._createJCDIInjectionContext(JCDIServiceImpl.java:182)
      at org.glassfish.weld.services.JCDIServiceImpl.createJCDIInjectionContext(JCDIServiceImpl.java:150)
      at com.sun.ejb.containers.BaseContainer.createEjbInstanceAndContext(BaseContainer.java:1632)
      at com.sun.ejb.containers.AbstractSingletonContainer.createSingletonEJB(AbstractSingletonContainer.java:418)
      ... 56 more
      Caused by: java.lang.reflect.InvocationTargetException
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:601)
      at org.jboss.weld.util.reflection.SecureReflections$13.work(SecureReflections.java:267)
      at org.jboss.weld.util.reflection.SecureReflectionAccess.run(SecureReflectionAccess.java:52)
      at org.jboss.weld.util.reflection.SecureReflectionAccess.runAsInvocation(SecureReflectionAccess.java:137)
      at org.jboss.weld.util.reflection.SecureReflections.invoke(SecureReflections.java:263)
      at org.jboss.weld.introspector.jlr.WeldMethodImpl.invoke(WeldMethodImpl.java:174)
      at org.jboss.weld.bean.AbstractClassBean.defaultPostConstruct(AbstractClassBean.java:402)
      ... 70 more
      Caused by: javax.ejb.EJBException: ds is null
      at com.acme.Bar.init(Bar.java:26)
      ... 80 more

      The Bar.java in its @PostConstruct checks the 'ds' value injected via

      @Resource(name="jdbc/__default") javax.sql.DataSource ds;

        Activity

        Hide
        marina vatkina added a comment -

        Note that this failure was observed on every other build starting 1/18, with the exceptions of failed builds in the last several days because of an error in embedded-static.shell.jar that had been fixed today.

        Show
        marina vatkina added a comment - Note that this failure was observed on every other build starting 1/18, with the exceptions of failed builds in the last several days because of an error in embedded-static.shell.jar that had been fixed today.
        Hide
        Tom Mueller added a comment -

        Reassigning to component lead as the assignee is no longer with the project.

        Show
        Tom Mueller added a comment - Reassigning to component lead as the assignee is no longer with the project.
        Hide
        guojun.shan added a comment -

        find this error message in server.log:
        [#|2013-02-21T16:02:16.853+0800|SEVERE|glassfish 4.0||_ThreadID=404;_ThreadName=Thread-4;_TimeMillis=1361433736853;_LevelValue=1000;|No valid EE environment for injection of com.acme.Bar|#]

        Show
        guojun.shan added a comment - find this error message in server.log: [#|2013-02-21T16:02:16.853+0800|SEVERE|glassfish 4.0||_ThreadID=404;_ThreadName=Thread-4;_TimeMillis=1361433736853;_LevelValue=1000;|No valid EE environment for injection of com.acme.Bar|#]
        Hide
        guojun.shan added a comment -

        in InjectionServicesImpl#aroundInject componentEnv == null
        because in ComponentEnvManagerImpl#getCurrentJndiNameEnvironment invMgr.getCurrentInvocation()==null

        Show
        guojun.shan added a comment - in InjectionServicesImpl#aroundInject componentEnv == null because in ComponentEnvManagerImpl#getCurrentJndiNameEnvironment invMgr.getCurrentInvocation()==null
        Hide
        guojun.shan added a comment -

        Now I know the exact case of failure:
        Both SingletonBeanA.java and SingletonBean2.java are defined @Startup, so they will both be initialized when deployed.
        If SingletonBeanA is init first, it will deployed failed. Otherwise, it pass. If you remove @startup from SingletonBean2 it will always failed.

        So CDI may not support this kind of case.

        Show
        guojun.shan added a comment - Now I know the exact case of failure: Both SingletonBeanA.java and SingletonBean2.java are defined @Startup, so they will both be initialized when deployed. If SingletonBeanA is init first, it will deployed failed. Otherwise, it pass. If you remove @startup from SingletonBean2 it will always failed. So CDI may not support this kind of case.
        Hide
        guojun.shan added a comment -

        BTW, it seems there is no InvocationManager.preInvoke() before InjectionServicesImpl#aroundInject for the failed case.

        Show
        guojun.shan added a comment - BTW, it seems there is no InvocationManager.preInvoke() before InjectionServicesImpl#aroundInject for the failed case.
        Hide
        guojun.shan added a comment -

        Could you re-assign to the proper developer for this issue?thanks.

        Show
        guojun.shan added a comment - Could you re-assign to the proper developer for this issue?thanks.
        Hide
        jwells added a comment -

        Here is a simple set of two classes that always has this issue:

        // @Singleton
        // @Startup
        public class JRW {

        @Resource(name="jdbc/__default") javax.sql.DataSource ds;

        public JRW()

        { System.out.println("Constructed::JRW " + System.identityHashCode(this)); }

        @PostConstruct
        public void init()

        { System.out.println("JRW ds inject = " + ds); }

        public String toString()

        { return "JRW"; }

        public void callMe() {
        }

        }

        and:

        @Singleton
        @Startup
        public class JRW2 {

        private final JRW jrw;

        @Inject
        public JRW2(JRW jrw)

        { this.jrw = jrw; System.out.println("Constructed::JRW2 " + System.identityHashCode(this)); }

        @PostConstruct
        public void init()

        { jrw.callMe(); System.out.println("JRW2 jrw = " + jrw); }

        public String toString()

        { return "JRW2"; }

        }

        In the "failing" case you will see the printout:

        JRW ds inject = null

        in the server.log (along with the above mentioned message in the log file).

        Here are interesting observations:

        1. If you instead use field injection in JRW2 (injecting JRW rather than sending it in via the constructor) then this case works
        2. If you make JRW an @Singleton then this case works

        So this is not random. Now that I have a consistent reproducer I'll look into why this is failing...

        Show
        jwells added a comment - Here is a simple set of two classes that always has this issue: // @Singleton // @Startup public class JRW { @Resource(name="jdbc/__default") javax.sql.DataSource ds; public JRW() { System.out.println("Constructed::JRW " + System.identityHashCode(this)); } @PostConstruct public void init() { System.out.println("JRW ds inject = " + ds); } public String toString() { return "JRW"; } public void callMe() { } } and: @Singleton @Startup public class JRW2 { private final JRW jrw; @Inject public JRW2(JRW jrw) { this.jrw = jrw; System.out.println("Constructed::JRW2 " + System.identityHashCode(this)); } @PostConstruct public void init() { jrw.callMe(); System.out.println("JRW2 jrw = " + jrw); } public String toString() { return "JRW2"; } } In the "failing" case you will see the printout: JRW ds inject = null in the server.log (along with the above mentioned message in the log file). Here are interesting observations: 1. If you instead use field injection in JRW2 (injecting JRW rather than sending it in via the constructor) then this case works 2. If you make JRW an @Singleton then this case works So this is not random. Now that I have a consistent reproducer I'll look into why this is failing...
        Hide
        jwells added a comment -

        Commit 60958 fixes the issue by ensuring a proper EJB context when creating EJBs in both the CDI and non-CDI cases.

        Show
        jwells added a comment - Commit 60958 fixes the issue by ensuring a proper EJB context when creating EJBs in both the CDI and non-CDI cases.

          People

          • Assignee:
            jwells
            Reporter:
            marina vatkina
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: