8 Replies Latest reply on Jan 21, 2009 10:50 AM by matt.nirgue

    Configuration question with TestNG Maven - components.xml?

    rdc2001

      Hello,

      How does Seam configure itself when running TestNG spawned by the Maven build process? As far as I can tell, it isn't reading my components.xml file. I created my project using the  archetype maven-archetype-webapp. The components.xml is stored under /src/main/webapp/WEB-INF. Adding random characters thereby making the file an invalid XML document doesn't break the unit tests (which aren't doing anything yet). How do I inform the SeamTest super class where to find the components.xml? Without components.xml I am not sure how it (Seam/SeamTest) would be able to setup the EntityManager etc.


      Thanks,

      -Ryan

        • 1. Re: Configuration question with TestNG Maven - components.xml?
          rdc2001

          A few more details - below is the error I am receiving.

          Setup:

          /test/resources/META-INF/persistence.xml

          /test/resources/WEB-INF/components.xml

          /test/resources/WEB-INF/web.xml

          /test/resources/seam.properties


          org.jboss.seam.InstantiationException: Could not instantiate Seam component: EmailScheduler
               at org.jboss.seam.Component.newInstance(Component.java:2106)
               at org.jboss.seam.contexts.Contexts.startup(Contexts.java:304)
               at org.jboss.seam.contexts.Contexts.startup(Contexts.java:278)
               at org.jboss.seam.contexts.ServletLifecycle.endInitialization(ServletLifecycle.java:112)
               at org.jboss.seam.init.Initialization.init(Initialization.java:735)
               at org.jboss.seam.mock.AbstractSeamTest.startSeam(AbstractSeamTest.java:919)
               at org.jboss.seam.mock.SeamTest.startSeam(SeamTest.java:58)
               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:585)
               at org.testng.internal.MethodHelper.invokeMethod(MethodHelper.java:604)
               at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:394)
               at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:142)
               at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:79)
               at org.testng.SuiteRunner.privateRun(SuiteRunner.java:261)
               at org.testng.SuiteRunner.run(SuiteRunner.java:190)
               at org.testng.TestNG.createAndRunSuiteRunners(TestNG.java:792)
               at org.testng.TestNG.runSuitesLocally(TestNG.java:765)
               at org.testng.TestNG.run(TestNG.java:699)
               at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:62)
               at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:141)
               at org.apache.maven.surefire.Surefire.run(Surefire.java:177)
               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:585)
               at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:338)
               at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:997)
          Caused by: java.lang.IllegalArgumentException: EntityManagerFactory not found in JNDI : java:/em
               at org.jboss.seam.persistence.ManagedPersistenceContext.getEntityManagerFactoryFromJndiOrValueBinding(ManagedPersistenceContext.java:245)
               at org.jboss.seam.persistence.ManagedPersistenceContext.initEntityManager(ManagedPersistenceContext.java:78)
               at org.jboss.seam.persistence.ManagedPersistenceContext.getEntityManager(ManagedPersistenceContext.java:107)
               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:585)
               at org.jboss.seam.util.Reflections.invoke(Reflections.java:22)
               at org.jboss.seam.util.Reflections.invokeAndWrap(Reflections.java:144)
               at org.jboss.seam.Component.callComponentMethod(Component.java:2211)
               at org.jboss.seam.Component.unwrap(Component.java:2237)
               at org.jboss.seam.Component.getInstance(Component.java:2004)
               at org.jboss.seam.Component.getInstance(Component.java:1950)
               at org.jboss.seam.Component.getInstance(Component.java:1944)
               at org.jboss.seam.Component.getInstanceInAllNamespaces(Component.java:2311)
               at org.jboss.seam.Component.getValueToInject(Component.java:2263)
               at org.jboss.seam.Component.injectAttributes(Component.java:1703)
               at org.jboss.seam.Component.inject(Component.java:1521)
               at org.jboss.seam.core.BijectionInterceptor.aroundInvoke(BijectionInterceptor.java:61)
               at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
               at org.jboss.seam.transaction.TransactionInterceptor$1.work(TransactionInterceptor.java:95)
               at org.jboss.seam.util.Work.workInTransaction(Work.java:47)
               at org.jboss.seam.transaction.TransactionInterceptor.aroundInvoke(TransactionInterceptor.java:89)
               at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
               at org.jboss.seam.core.MethodContextInterceptor.aroundInvoke(MethodContextInterceptor.java:44)
               at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
               at org.jboss.seam.async.AsynchronousInterceptor.aroundInvoke(AsynchronousInterceptor.java:52)
               at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
               at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:107)
               at org.jboss.seam.intercept.JavaBeanInterceptor.interceptInvocation(JavaBeanInterceptor.java:185)
               at org.jboss.seam.intercept.JavaBeanInterceptor.invoke(JavaBeanInterceptor.java:103)
               at org.ctjava.admin.EmailScheduler_$$_javassist_0.startup(EmailScheduler_$$_javassist_0.java)
               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:585)
               at org.jboss.seam.util.Reflections.invoke(Reflections.java:22)
               at org.jboss.seam.util.Reflections.invokeAndWrap(Reflections.java:144)
               at org.jboss.seam.Component.callComponentMethod(Component.java:2211)
               at org.jboss.seam.Component.callCreateMethod(Component.java:2134)
               at org.jboss.seam.Component.newInstance(Component.java:2094)
               ... 28 more


          • 2. Re: Configuration question with TestNG Maven - components.xml?
            matt.nirgue

            This is most likely a classpath issue... here's what I added in the POM file of my project to make it works:



            <build>
              <testResources>
                <testResource>
                  <directory>src/test/bootstrap</directory>
                </testResource>
                <testResource>
                  <directory>src/test/resources</directory>
                </testResource>
              </testResources>
              ...
              <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                  <argLine>-Xmx512m</argLine>
                </configuration>
              </plugin>
            </build>
            



            Hope this will also work for you...


            Regards,


            Matt

            • 3. Re: Configuration question with TestNG Maven - components.xml?
              rdc2001

              Thanks but that didn't work.


              The thing I don't understand - who is building JNDI? I am not running inside of a container. Maven kicks off TestNG as a part of the build process, detects my tests, and runs them. Skimming the source for AbstractSeamTest I didn't see JNDI being mocked. I did create a persistence.xml file that doesn't acquire the database connection from JNDI (hibernate direct connect) but I am still seeing a reference to java:/em in the stacktrace pasted below.

              Perusing the code I did come across SeamDBUnitTest. It looks like that is also pulling from JNDI. Are the SeamTests supposed to run inside of a container?



              So, my SeamTest is blowing up when it instantiates a bean on startup:


              @Name("EmailScheduler")
              @Scope(ScopeType.APPLICATION)
              @Startup(depends="quartz-dispatcher")
              public class EmailScheduler {
              
                  private static final Logger logger = Logger.getLogger(EmailScheduler.class);
              
                  @In(create=true)
                  private EntityManager em;
              
                  @In
                  private Renderer renderer;
              
                  @Create
                  public void startup() {
                      if(logger.isDebugEnabled()) {
                          logger.debug("Starting the email scheduler...");
                      }
                      Date dt = new Date(new Date().getTime()+2000);
                      startScan(dt);
              
                  }
              
                  @Asynchronous
                  @Transactional
                  public QuartzTriggerHandle startScan(@Expiration Date when) {
                      System.out.println("We have executed!!");
                      return null;
                  }
              }




              Stacktrace bits:


              startSeam(org.ctjava.camp.TestRegistration)  Time elapsed: 0 sec   FAILURE!<br/>
              org.jboss.seam.InstantiationException: Could not instantiate Seam component: EmailScheduler
              ...
              ...
              Caused by: java.lang.IllegalArgumentException: EntityManagerFactory not found in JNDI : java:/em
                   at org.jboss.seam.persistence.ManagedPersistenceContext.getEntityManagerFactoryFromJndiOrValueBinding(ManagedPersistenceContext.java:245)
              ...
              ...
              Caused by: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial
              
              



              Components.xml


                  <core:manager conversation-timeout="120000"
                                concurrent-request-timeout="500"
                                conversation-id-parameter="cid"/>
              
                  <core:resource-loader bundle-names="messages,msg"/>
              
              
              
                  <persistence:entity-manager-factory name="registrationDatabase"/>
              
                  <persistence:managed-persistence-context name="em" auto-create="true"
                                                           entity-manager-factory="#{testDatabase}"/>
              
                  <transaction:entity-transaction entity-manager="#{em}"/>
              
                  <security:identity authenticate-method="#{AuthenticateAction.authenticate}"/>
              
                  <mail:mail-session session-jndi-name="java:comp/env/mail/Session"/>
                               
                  <async:quartz-dispatcher/>




              Thanks,

              -Ryan


               

              • 4. Re: Configuration question with TestNG Maven - components.xml?
                matt.nirgue

                When you want to do integration tests (which seems to be the case here), your tests need to be run inside a container... Either you deploy your tests on a server, or you use Embedded JBoss... This will allow you to test persistance, in(/out)jection, etc...


                If you haven't changed the default behavior of your test classes, Seam starts as soon as a test suite starts running (startSeam())... Actually, if you take a look at this function, you'll find that -before anything else- it tries to start Embedded JBoss (if it's available)... Otherwise, I guess it assumes that your tests are running on a server so it won't try to start embedded jboss...


                To sum it up: if you want to do some complex tests (and not just some unit testing), you'll need an integration environment with a container, a database, etc.


                Matt

                • 5. Re: Configuration question with TestNG Maven - components.xml?
                  rdc2001

                  Thanks!

                  That's the explanation I was looking for. I don't suppose anyone has launched the tests in a container from Maven?


                  -Ryan

                  • 6. Re: Configuration question with TestNG Maven - components.xml?
                    matt.nirgue

                    What exactly do you mean by launch the tests in a container from Maven? you'd like to run your tests with just mvn clean test is that it? Because if that's what you're asking, then it's definitely possible (this is how I launch my tests)

                    • 7. Re: Configuration question with TestNG Maven - components.xml?
                      rdc2001

                      From the previous post - my integration tests (as they presently stand) require a container with JNDI. For instance, I have a Seam bean annotated with @Transactional and this bean is created on startup. Since I am not running in a container - Seam is unable to lookup a transaction manager and all of the unit tests fail.

                      I will disable this Seam bean as I don't want it running anyway during the tests.

                      • 8. Re: Configuration question with TestNG Maven - components.xml?
                        matt.nirgue

                        Why don't you try to use Embedded Jboss as an integration environment? You wouldn't have to enable/disable your components every time you want to launch your tests and you'd be able to test the whole project and not just POJOs, etc. Just my opinion though.