8 Replies Latest reply on Oct 1, 2010 3:54 AM by robgartman

    @Inject fails in tested code but works in test class

    robgartman

      I have troubbles getting  CDI injection working when injection is happening in other classes than the actual test class. I try to inject a bean into a class being referenced by the test case but I end up with a null object every time. However, injection within the test class itself works just fine. I'm rather new to CDI and these failures makes me wonder if it's even supposed to work.

       

      The code below is an example of what I'm trying to do. First the "MyInjectedClass" class:

       

      @Dependent
      public class MyInjectClass {
          Logger logger = LoggerFactory.getLogger(this.getClass());
      
          public MyInjectClass() {
              logger.info("MyInjectClass instantiated");
          }
      }
      

       

      I want to inject MyInjectedClass above in MyClass below.

       

      @ApplicationScoped
      public class MyClass {
      
          Logger logger = LoggerFactory.getLogger(this.getClass());
          
          @Inject MyInjectClass myInjectClass;
          
          public MyClass(){
              logger.info("Myclass OK");
              logger.info("myInjectClass={}",myInjectClass);        
          }
          
          Object getInjectedObject(){
              return myInjectClass;
          }
      }
      

       

      And this is my test setup. Test1 succeeds and Test2 fails since the "@Inject MyInjectClass myInjectClass;" results in a null object.

       

      @RunWith(Arquillian.class)
      @Run(RunModeType.IN_CONTAINER)
      public class TestSuite {
      
          @Deployment
          public static Archive<?> createDeploymentPackage() {
              return ShrinkWrap.create(JavaArchive.class, "test.jar").addPackages(true, MyClass.class.getPackage())
                      .addManifestResource(new ByteArrayAsset("<beans />".getBytes()), ArchivePaths.create("beans.xml"));
          }
      
          @Inject
          MyClass myClass;
      
          @Test
          public void Test1() throws Exception {
              Assert.assertNotNull("Injection did not work from within TestSuite",myClass);
          }
          
          @Test
          public void Test2() throws Exception {
              Assert.assertNotNull("Injection did not work from within MyClass",myClass.getInjectedObject());
          }
      }
      

       

       

      My environment is:

       

      Apache Maven 3.0-beta-3 (r990787; 2010-08-30 14:44:03+0200)
      Java version: 1.6.0_21
      OS name: "windows 7" version: "6.1" arch: "amd64" Family: "windows"
      
      Tests are running on Glassfish embedded v.3.1-b20 and Arquillian 1.0.0.Alpha4.SP1
      

       

      The Maven Surefire output:

       

      2010-sep-30 22:17:47 com.sun.enterprise.glassfish.bootstrap.EmbeddedNonOSGiGlassFishRuntimeBuilder provisionInstanceRoot
      VARNING: AS_DEF_DOMAINS_PATH is not set.
      2010-sep-30 22:17:48 com.sun.enterprise.util.EarlyLogger add
      INFO: Total time to parse domain.xml: 79 milliseconds
      2010-sep-30 22:17:50 com.sun.logging.LogDomains$1 log
      INFO: GlassFish Server Open Source Edition 3.1-b20 (java_re-private) startup time : Embedded(454ms) startup services(2482ms) total(2936ms)
      2010-sep-30 22:17:50 com.sun.logging.LogDomains$1 log
      INFO: enterprise_used_delegate_name
      2010-sep-30 22:17:50 com.sun.logging.LogDomains$1 log
      INFO: JMXStartupService: JMXConnector system is disabled, skipping.
      2010-sep-30 22:17:50 AppServerStartup run
      INFO: [Thread[GlassFish Kernel Main Thread,5,main]] started
      2010-sep-30 22:17:50 org.glassfish.web.embed.impl.EmbeddedWebContainerImpl bind
      INFO: EmbeddedWebContainer binding port 8181 protocol http
      2010-sep-30 22:17:50 org.hibernate.validator.util.Version <clinit>
      INFO: Hibernate Validator null
      2010-sep-30 22:17:50 org.hibernate.validator.engine.resolver.DefaultTraversableResolver detectJPA
      INFO: Instantiated an instance of org.hibernate.validator.engine.resolver.JPATraversableResolver.
      2010-sep-30 22:17:51 com.sun.enterprise.v3.server.DomainXmlPersistence save
      ALLVARLIG: domain.xml cannot be persisted, null destination
      2010-sep-30 22:17:51 com.sun.enterprise.v3.server.DomainXmlPersistence save
      ALLVARLIG: domain.xml cannot be persisted, null destination
      2010-sep-30 22:17:51 com.sun.enterprise.v3.services.impl.GrizzlyProxy$2$1 onReady
      INFO: Grizzly Framework 1.9.19 started in: 72ms - bound to [0.0.0.0:8181]
      2010-sep-30 22:17:51 com.sun.enterprise.v3.server.DomainXmlPersistence save
      ALLVARLIG: domain.xml cannot be persisted, null destination
      2010-sep-30 22:17:52 com.sun.enterprise.v3.services.impl.GrizzlyProxy$2$1 onReady
      INFO: Grizzly Framework 1.9.19 started in: 4ms - bound to [0.0.0.0:8181]
      2010-sep-30 22:17:52 org.jboss.arquillian.impl.DynamicServiceLoader verifySameImplementation
      VARNING: More then one reference to the same implementation was found for org.jboss.arquillian.spi.DeploymentPackager, please verify you classpath
      2010-sep-30 22:17:52 org.jboss.arquillian.impl.DynamicServiceLoader verifySameImplementation
      VARNING: More then one reference to the same implementation was found for org.jboss.arquillian.spi.ApplicationArchiveGenerator, please verify you classpath
      2010-sep-30 22:17:52 org.jboss.shrinkwrap.impl.base.ServiceExtensionLoader findExtensionImpl
      VARNING: Multiple extension implementations found for org.jboss.shrinkwrap.api.spec.JavaArchive, please verify classpath or add a extensionOverride
      2010-sep-30 22:17:52 org.jboss.shrinkwrap.impl.base.ServiceExtensionLoader findExtensionImpl
      VARNING: Multiple extension implementations found for org.jboss.shrinkwrap.api.spec.WebArchive, please verify classpath or add a extensionOverride
      2010-sep-30 22:17:52 org.jboss.shrinkwrap.impl.base.ServiceExtensionLoader findExtensionImpl
      VARNING: Multiple extension implementations found for org.jboss.shrinkwrap.glassfish.api.ShrinkwrapReadableArchive, please verify classpath or add a extensionOverride
      2010-sep-30 22:17:52 org.jboss.shrinkwrap.impl.base.ServiceExtensionLoader findExtensionImpl
      VARNING: Multiple extension implementations found for org.jboss.shrinkwrap.api.exporter.ZipExporter, please verify classpath or add a extensionOverride
      2010-sep-30 22:17:52 org.jboss.shrinkwrap.impl.base.ServiceExtensionLoader findExtensionImpl
      VARNING: Multiple extension implementations found for org.jboss.shrinkwrap.spi.Configurable, please verify classpath or add a extensionOverride
      2010-sep-30 22:17:53 com.sun.logging.LogDomains$1 log
      INFO: security.secmgroff
      2010-sep-30 22:17:53 com.sun.logging.LogDomains$1 log
      INFO: sec.service.startup.enter
      2010-sep-30 22:17:53 com.sun.logging.LogDomains$1 log
      INFO: policy.loading
      2010-sep-30 22:17:53 com.sun.logging.LogDomains$1 log
      INFO: realm.loaded.successfully
      2010-sep-30 22:17:53 com.sun.logging.LogDomains$1 log
      INFO: realm.loaded.successfully
      2010-sep-30 22:17:53 com.sun.logging.LogDomains$1 log
      INFO: realm.loaded.successfully
      2010-sep-30 22:17:53 com.sun.logging.LogDomains$1 log
      INFO: sec.service.startup.exit
      2010-sep-30 22:17:53 com.sun.common.util.logging.LoggingConfigImpl openPropFile
      INFO: Cannot read logging.properties file. 
      2010-sep-30 22:17:53 com.sun.logging.LogDomains$1 log
      INFO: webContainer.HTTP.listenerAndPort
      2010-sep-30 22:17:53 com.sun.logging.LogDomains$1 log
      INFO: webContainer.virtualServer.created
      2010-sep-30 22:17:54 com.sun.logging.LogDomains$1 log
      INFO: PersistenceStrategyBuilderFactory>>createPersistenceStrategyBuilder: CandidateBuilderClassName = class com.sun.enterprise.web.MemoryStrategyBuilder
      2010-sep-30 22:17:54 com.sun.logging.LogDomains$1 log
      INFO: webContainer.virtualServer.loadedDefaultWebModule
      classLoader = WebappClassLoader (delegate=true; repositories=WEB-INF/classes/)
      SharedSecrets.getJavaNetAccess()=java.net.URLClassLoader$7@6ea53502
      2010-sep-30 22:18:03 org.jboss.weld.bootstrap.WeldBootstrap <clinit>
      INFO: WELD-000900 SNAPSHOT
      2010-sep-30 22:18:03 org.hibernate.validator.engine.resolver.DefaultTraversableResolver detectJPA
      INFO: Instantiated an instance of org.hibernate.validator.engine.resolver.JPATraversableResolver.
      2010-sep-30 22:18:04 com.sun.logging.LogDomains$1 log
      INFO: PersistenceStrategyBuilderFactory>>createPersistenceStrategyBuilder: CandidateBuilderClassName = class com.sun.enterprise.web.MemoryStrategyBuilder
      2010-sep-30 22:18:04 com.sun.logging.LogDomains$1 log
      INFO: webApplication.loadingApplication
      2010-sep-30 22:18:04 MyClass <init>
      INFO: Myclass OK
      2010-sep-30 22:18:04 MyClass <init>
      INFO: myInjectClass=null

       

      Are there any helpful minds in the community who can tell me what's wrong?

       

      Best regards

      Robert

        • 1. Re: @Inject fails in tested code but works in test class
          aslak

          Your post seems to be missing some of the code, but.. using this as @Deployment

           

           

             @Deployment
             public static Archive<?> deploy()
             {
                return ShrinkWrap.create(JavaArchive.class)
                   .addClasses(MyClass.class, MyInjectClass.class)
                   .addManifestResource(EmptyAsset.INSTANCE, "beans.xml");
             }
           
          
          
          

           

          works fine in the weld-se-embedded-1 container...

           

          Your log statements in MyClass will always print that the injected object is null, since it needs to create a instance of the object before it can inject anything into it.. but beyond that I can't see anything wrong with what your doing..

           

          -aslak-

          • 2. Re: @Inject fails in tested code but works in test class
            robgartman

            Aslak - Thanks for your fast reply!

             

            I have verified that both versions of @Deployment code snippets work well when running against weld-se-embedded-1 (passing Test1 and Test2). I see your point (now) about the logging always showing a null result. However, I need an EE container for my testing and the test does not pass with glassfish embedded. Bug?

             

            -Robert

            • 3. Re: @Inject fails in tested code but works in test class
              dan.j.allen

              Your assert only fails on GlassFish 3.1-b20. If you switch the version of GlassFish to 3.0.1 then it works fine. It also works in Embedded Weld and JBoss AS 6. This could either indicate a container bug in GlassFish 3.1 or what you are doing is not to spec (I can't remember if injection points are satisfied before invoking the bean constructor...though my instinct is to say they are).

               

              Your Arquillian setup is correct.

              1 of 1 people found this helpful
              • 4. Re: @Inject fails in tested code but works in test class
                aslak

                How can the InjectionPoint be satisfied before invoking the constructor? Welds needs a Object to inject into, to get a Object from a Class you need to construct it.

                 

                Spec or not, the test should still pass, since the test checks the status of calling getInjectedObject after the Object is constructed.

                 

                Sounds like a container bug..

                1 of 1 people found this helpful
                • 5. Re: @Inject fails in tested code but works in test class
                  robgartman

                  Dan and Aslak

                   

                  I ran the code on arquillian-jbossas-embedded-6 (JBoss AS  6.0.0.20100721-M4) and it failed.

                   

                  I'm very thankful about your hint about Glassfish 3.0.1. It works! I'll leave it to you to judge if it is container or code.

                   

                  Thanks

                  Robert

                  • 6. Re: @Inject fails in tested code but works in test class
                    aslak

                    JBoss AS 6 Embedded failed on the same? or something else ?

                     

                    They all use the same CDI Container in one version or the other, so..

                    • 7. Re: @Inject fails in tested code but works in test class
                      dan.j.allen

                      Aslak Knutsen wrote:

                       

                      How can the InjectionPoint be satisfied before invoking the constructor? Welds needs a Object to inject into, to get a Object from a Class you need to construct it.

                       

                      Hahaha. Good point. I don't know what I was thinking

                      • 8. Re: @Inject fails in tested code but works in test class
                        robgartman

                        Aslak Knutsen wrote:

                         

                        JBoss AS 6 Embedded failed on the same? or something else ?

                         

                        The same code has been used for all tests. It's the one in my original post in this thread. Arquillian 1.0.0.Alpha4.SP1 has been used in all tests.

                         

                        Conclusion:

                         

                        The "Test2" test case is working on Weld SE Embedded and Glassfish Embedded 3.0.1, but fails on Glassfish Embedded 3.1-b20 and JBoss Embedded AS 6 M4.