6 Replies Latest reply on Nov 29, 2012 3:22 AM by iapazmino

    java.lang.NoSuchFieldError: ENVIRONMENT when run as a client

    iapazmino

      Hello,

       

      Right now I need my (war) deployment to be enriched to get access to the persistence context and setup the database, and then, run the test as a client to check some auto-loaded content. To do so, I've made the deployment testable and marked the test to run as a client

       

          @Deployment 
          public static WebArchive createDeployable() {
              final WebArchive war = ShrinkWrap.create(WebArchive.class, "test.war") 
                      ... 
                      .addAsResource("META-INF/persistence.xml", "META-INF/persistence.xml") 
                      .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml") 
                      .addAsWebInfResource( 
                              new StringAsset("<faces-config version=\"2.0\"/>"), "faces-config.xml"); 
              return war; 
          }
      
          @Test
          @RunAsClient 
          public void shouldAutoLoadDestinataries() { 
              ...
              assertEquals(SUBJECT, browser.getValue("id=agreementForm:subject")); 
          }
      

       

      This causes the following exception during deployment

       

      ERROR [org.jboss.msc.service.fail] (MSC service thread 1-4) MSC00001: Failed to start service jboss.deployment.unit.arquillian-service.INSTALL: org.jboss.msc.service.StartException in service jboss.deployment.unit.arquillian-service.INSTALL: Failed to process phase INSTALL of deployment "arquillian-service"
          at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:119) [jboss-as-server-7.1.1.Final.jar:7.1.1.Final]
          at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
          at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
          at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) [rt.jar:1.6.0_31]
          at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) [rt.jar:1.6.0_31]
          at java.lang.Thread.run(Thread.java:662) [rt.jar:1.6.0_31]
      Caused by: java.lang.NoSuchFieldError: ENVIRONMENT
          at org.jboss.as.arquillian.service.ArquillianService.addService(ArquillianService.java:88)
          at org.jboss.as.arquillian.service.ArquillianServiceActivator.activate(ArquillianServiceActivator.java:41)
          at org.jboss.as.server.deployment.service.ServiceActivatorProcessor.deploy(ServiceActivatorProcessor.java:62) [jboss-as-server-7.1.1.Final.jar:7.1.1.Final]
          at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:113) [jboss-as-server-7.1.1.Final.jar:7.1.1.Final]
          ... 5 more
      

       

      If I remove the @RunAsClient annotation from the test and mark the @Deployment with (testable = false) the server starts but setup fails as the persistence components I need are not provided.

       

      The boms I'm using are

       

                  <dependency>
                      <groupId>org.jboss.arquillian</groupId>
                      <artifactId>arquillian-bom</artifactId>
                      <version>1.0.3.Final</version>
                      <type>pom</type>
                      <scope>import</scope>
                  </dependency>
                  <dependency>
                      <groupId>org.jboss.arquillian.extension</groupId>
                      <artifactId>arquillian-drone-bom</artifactId>
                      <version>1.1.0.Final</version>
                      <type>pom</type>
                      <scope>import</scope>
                  </dependency>
                  <dependency>
                      <groupId>org.jboss.as</groupId>
                      <artifactId>jboss-as-arquillian-container-managed</artifactId>
                      <version>7.1.2.Final</version>
                      <scope>test</scope>
                  </dependency>
      

       

      Any ideas where the problems might be at?

       

      Thanks in advance

        • 1. Re: java.lang.NoSuchFieldError: ENVIRONMENT when run as a client
          vineet.reynolds

          I ran into something similar a few hours back. Not sure what resolved it, but it is one of these:

           

          1. Use org.jboss.as:jboss-as-arquillian-container-managed:7.1.1.Final in your POM. You seem to be running against AS 7.1.1 while using the container adapter of 7.1.2 - this can happen if you let Forge use the default versions for all the dependencies.

          2. Switch to the servlet protocol. The default JMX protocol is a bit hard to debug, when it comes to debugging deployment failures.

           

          Edit - Found the actual cause of my problem - it was the JMX protocol in use. Switching to the Servlet protocol fixed the issue. A CDI interceptor defined in my ShrinkWrap JavaArchive resulted in this  error.

          • 2. Re: java.lang.NoSuchFieldError: ENVIRONMENT when run as a client
            iapazmino

            Thank you very much, changing the version fixed the ENVIRONMENT error, but now the com.thoughtworks.selenium.DefaultSelenium class was not found for WELD to inject it. Maybe switching the protocol, how do I switch to the Servlet protocol? I do have the dependency in my pom

             

                    <dependency>
                        <groupId>org.jboss.arquillian.protocol</groupId>
                        <artifactId>arquillian-protocol-servlet</artifactId>
                        <scope>test</scope>
                    </dependency>
            
            • 3. Re: java.lang.NoSuchFieldError: ENVIRONMENT when run as a client
              vineet.reynolds

              Details on how to use the Servlet protocol instead of JMX for the AS7 container are provided in this FAQ note. But that is not related to the Weld failure.

               

              Weld doesnt "inject" DefaultSelenium into your test class instance, since it doesnt recognize the @Drone annotation. It's just that Weld is unable to find the DefaultSelenium class when it processes the classes in the BDA of your deployment. Note that the CNFE encountered by Weld (when it processes your test class) should not result in a deployment failure. You may in fact want to set the testable attribute on the @Deployment to false, as noted in the Drone documentation, but that is not necessary if you use @RunAsClient.

              • 4. Re: java.lang.NoSuchFieldError: ENVIRONMENT when run as a client
                iapazmino

                Yes, actually that's how all started: I need the @PersistenceContext and the @Inject javax.transaction.UserTransaction in the test to setup  the database and @Drone's DefaultSelenium to check the info was loaded.

                 

                So, the @Deployment is testable but the @Test is @RunAsClient. With this configuration I get the DefaultSelenium's CNFE. The CNFE occurs when WELD is loading beans definitions, but it doesn't stop the deployment. When the test is run a NPE is thrown when the UserTransaction is invoked.

                 

                If Ichange it to @Deployment is not testable and remove the @RunAsClient from the test results in NPE when using the UserTransaction. Here the deployment is without a single error, but as soon as it tries to use the transaction the NPE is thrown.

                 

                Besides the @Deployment and @Test methods, these members are in the test class

                 

                    @Drone
                    protected DefaultSelenium browser;
                
                    @ArquillianResource
                    protected URL deploymentUrl;
                
                    @PersistenceContext
                    protected EntityManager entityManager;
                
                    @Inject
                    protected UserTransaction txn;
                
                
                • 5. Re: java.lang.NoSuchFieldError: ENVIRONMENT when run as a client
                  vineet.reynolds

                  I get what you're trying to do now. Unfortunately, the very CNFE you encounter causes Weld to not inject the EntityManager and the UserTransaction into the testclass instance.

                   

                  To explain further, Arquillian uses the CDI BeanManager if it can get access to one, to inject dependencies into the test class. The test class is not a CDI bean, but the CDI test enricher treats it as one. The CDI BeanManager is capable of injecting the EntityManager and UserTransactions into the test class instance; this is actually something supported by the CDI 1.0 spec. I suspect Weld will encounter a similar problem when it attempts to inject resources into the injection points. That would explain why the entityManager and the txn fields would be null.

                   

                  I think I'm making assumptions about your test suite when I say that the best way to deal with this problem is to setup the database during deployment using import.sql (if you're using Hibernate) or a ServletContextListener or maybe even DbUnit (in the @BeforeClass method that runs only at the client), instead of relying on logic that executes in your test.

                  • 6. Re: java.lang.NoSuchFieldError: ENVIRONMENT when run as a client
                    iapazmino

                    Thank you for your help Vineet, I've setup the hibernate.hbm2ddl.import_files while I find a way to work together with the arquillian-peristence-extension