6 Replies Latest reply on Dec 27, 2007 2:16 AM by sushmu

    Entity EJB3.0 Unit Testing - How to setup JNDI datasource?

    sushmu

      I'm using maven and not seam-gen. I have a simple entity User and a unit test.

      I'm referring Seam 2.0 examples in the test creation.

      Here's the snippets:

      UserTest:

      public class UserTest
       extends SeamTest
      {
       EntityManager em() {
       EntityManagerFactory emf = Persistence.createEntityManagerFactory("intellidocs");
       EntityManager em = emf.createEntityManager();
       assertNotNull("entity manager", em);
       assertTrue("entity manager open", em.isOpen());
       return em;
       }


      persistence.xml

      <persistence-unit name="intellidocs">
       <jta-data-source>java:/intellidocsDS</jta-data-source>
      


      pgsql-ds.xml

      <datasources>
       <local-tx-datasource>
      
       <!-- The jndi name of the DataSource, it is prefixed with java:/ -->
       <!-- Datasources are not available outside the virtual machine -->
       <jndi-name>intellidocsDS</jndi-name>
      
       <connection-url>jdbc:postgresql://localhost:5432/test</connection-url>
      
       <!-- The driver class -->
       <driver-class>org.postgresql.Driver</driver-class>
      
      


      All of them are present in test/resources.

      I run mvn:test

      and here's the error:

      -------------------------------------------------------
       T E S T S
      -------------------------------------------------------
      Running com.ibt.intellidocs.dummy.UserTest
      12:20:55,752 INFO Version:15 - Hibernate EntityManager 3.2.1.GA
      12:20:55,777 INFO Version:15 - Hibernate Annotations 3.2.1.GA
      12:20:55,794 INFO Environment:509 - Hibernate 3.2.3
      12:20:55,802 INFO Environment:542 - hibernate.properties not found
      12:20:55,807 INFO Environment:676 - Bytecode provider name : cglib
      12:20:55,815 INFO Environment:593 - using JDK 1.4 java.sql.Timestamp handling
      12:20:56,697 INFO AnnotationBinder:388 - Binding entity from annotated class: com.ibt.intellidocs.dummy.User
      12:20:56,757 INFO EntityBinder:378 - Bind entity com.ibt.intellidocs.dummy.User on table DUMMYUSER
      12:20:56,960 INFO NamingHelper:26 - JNDI InitialContext properties:{}
      12:20:56,966 INFO MemoryContextFactory:34 - Creating EJB3Unit initial JNDI context
      12:20:56,972 FATAL DatasourceConnectionProvider:55 - Could not find datasource: java:/intellidocsDS
      javax.naming.NamingException: Can't find the name (intellidocsDS) in the JNDI tree Current bindings>({})
       at com.bm.jndi.MemoryContext.lookup(MemoryContext.java:38)
       at javax.naming.InitialContext.lookup(InitialContext.java:392)
       at org.hibernate.connection.DatasourceConnectionProvider.configure(DatasourceConnectionProvider.java:52)
       at org.hibernate.connection.ConnectionProviderFactory.newConnectionProvider(ConnectionProviderFactory.java:124)
       at org.hibernate.ejb.InjectionSettingsFactory.createConnectionProvider(InjectionSettingsFactory.java:29)
       at org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:62)
       at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:2009)
       at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1292)
       at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:713)
       at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:121)
       at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:83)
       at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:60)
       at com.ibt.intellidocs.dummy.UserTest.em(UserTest.java:21)
       at com.ibt.intellidocs.dummy.UserTest.testRequiredAttributes(UserTest.java:50)
       at com.ibt.intellidocs.dummy.UserTest$1.testComponents(UserTest.java:37)
       at org.jboss.seam.mock.BaseSeamTest$ComponentTest.run(BaseSeamTest.java:167)
       at com.ibt.intellidocs.dummy.UserTest.runTests(UserTest.java:32)
       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.testng.internal.MethodHelper.invokeMethod(MethodHelper.java:552)
       at org.testng.internal.Invoker.invokeMethod(Invoker.java:407)
       at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:778)
       at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:105)
       at org.testng.TestRunner.privateRun(TestRunner.java:682)
       at org.testng.TestRunner.run(TestRunner.java:566)
       at org.testng.SuiteRunner.privateRun(SuiteRunner.java:220)
       at org.testng.SuiteRunner.run(SuiteRunner.java:146)
       at org.testng.TestNG.createAndRunSuiteRunners(TestNG.java:713)
       at org.testng.TestNG.runSuitesLocally(TestNG.java:676)
       at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.executeTestNG(TestNGDirectoryTestSuite.java:195)
       at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:133)
       at org.apache.maven.surefire.Surefire.run(Surefire.java:132)
       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.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:308)
       at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:879)
      12:20:57,040 INFO AnnotationBinder:388 - Binding entity from annotated class: com.ibt.intellidocs.dummy.User
      12:20:57,041 INFO EntityBinder:378 - Bind entity com.ibt.intellidocs.dummy.User on table DUMMYUSER
      12:20:57,060 INFO NamingHelper:26 - JNDI InitialContext properties:{}
      12:20:57,062 FATAL DatasourceConnectionProvider:55 - Could not find datasource: java:/intellidocsDS
      


      Now the question.. How do I make the datasource available to SeamTest through JNDI?

        • 1. Re: Entity EJB3.0 Unit Testing - How to setup JNDI datasourc
          sushmu

          After searching it seams (pun intended) like caveatemptor jpa example is the best bet for doing entity bean testing with an embedded ejb3 datasource.

          Hi Gavin, have any plans embracing Maven?? The seam community can greatly benefit from a maven seam-gen ;)

          • 2. Re: Entity EJB3.0 Unit Testing - How to setup JNDI datasourc
            pmuir

            Although I'm not Gavin,

            http://jira.jboss.com/jira/browse/JBSEAM-2026

            You'll need some way to make the DS available via JNDI (register the DS in JNDI).

            The simplest solution is to run in a integration test environment e.g. Embedded JBoss. There are discussions on the forum on how to make this best work, and this issue http://jira.jboss.com/jira/browse/JBSEAM-2371 to fix the problem.

            • 3. Re: Entity EJB3.0 Unit Testing - How to setup JNDI datasourc
              sushmu

              Thanks Pete. I'm more interested in running Embedded JBoss with a datasource rather than EJB3Unit. I know Seam 2.0 is full of examples on Embedded JBoss but it has the seam-gen magic built in.

              Right now I'm following the Hibernate CaveatEmptor examples, but that might be using an older version of Embedded Jboss. I'll check out the links that you have provided. Thanks.

              • 4. Re: Entity EJB3.0 Unit Testing - How to setup JNDI datasourc
                pmuir

                Running Embedded JBoss from Maven is, I believe, currently tricky due to classpath problems. However, with care you can set up the classpath correctly I hope. You need only theses jars:

                *hibernate-all.jar
                *jboss-embedded-all.jar
                *jboss-deployers.jar
                *thirdparty-all.jar
                *jboss-seam.jar
                *jsf-api.jar
                *el-api.jar
                *activation.jar
                *jboss-embedded-api.jar
                *jboss-el.jar

                CavaetEmptor probably uses Embedded EJB3 unless Christian updated it recently...

                • 5. Re: Entity EJB3.0 Unit Testing - How to setup JNDI datasourc
                  sushmu

                  Running Embedded JBoss from Maven is tricky partly because of the classpath issues and partly because of the surefire test plugin and the jdk 1.6 incompatabilities.

                  I did the following:

                  1. Download Embedded JBoss Beta 2 version.
                  2. Copy all folders under 'bootstrap' that comes with EJ into src/test/resources folder.
                  3. Configure the surefire test plugin with the necessary hacks.

                  Now I'm able to run EJ and deploy the EJB's. I've successfully unit tested an Entity EJB with the built in HSQL datasource. Next step.. Test the Session Beans (this has seam functionality).. Seam has to be configured next with Embedded JBoss and maven.

                  This entire exercise of making Maven2 + Seam2 + EJB3 + Embedded JBoss Beta2 + Unit/Integration Testing is making me go insane.

                  MORAL: Unless you have unlimited time to waste, dont try this. Use seam-gen instead.

                  • 6. Re: Entity EJB3.0 Unit Testing - How to setup JNDI datasourc
                    sushmu

                    Finally Integration testing of EJB works with Maven!

                    I have 3 modules as described in Maven guide.

                    1. EJB
                    2. WAR
                    3. EAR

                    Entity beans testing is done in EJB module as described in previous post.

                    Session beans testing is done in WAR module since it requires the servlet/facelet functionality. One additional step on top of the previous explanation was to copy 'components.xml' in 'target/test-classes/WEB-INF' folder.

                    The Action to test:

                    package com.ibt.intellidocs.dummy;
                    
                    import static org.jboss.seam.ScopeType.EVENT;
                    import org.jboss.seam.log.Log;
                    
                    import javax.persistence.EntityManager;
                    import java.io.Serializable;
                    import java.util.List;
                    
                    @Stateful
                    @Scope(EVENT)
                    @Name("dummyUserAction")
                    public class DummyUserAction
                     implements IDummyUserLocal, Serializable
                    {
                     @Logger
                     Log log;
                    
                     @In(required = true)
                     private DummyUser dummyUser;
                    
                     @PersistenceContext
                     private EntityManager entityManager;
                    
                     private String verify;
                     private boolean registered;
                    
                     public DummyUser findDummyUser(long id)
                     {
                     return entityManager.find(DummyUser.class, id);
                     }
                    
                     public long register()
                     {
                     if (dummyUser.getPassword().equals(verify))
                     {
                     List existing = entityManager.createQuery
                     ("select u.username from DummyUser u where u.username=#{dummyUser.username}")
                     .getResultList();
                     if (existing.size() == 0)
                     {
                     entityManager.persist(dummyUser);
                     log.info("Username #{dummyUser.username} already exists");
                     registered = true;
                     }
                     else
                     {
                     log.info("Username #{dummyUser.username} already exists");
                     }
                     }
                     else
                     {
                     log.info("Re-enter your password");
                     verify = null;
                     }
                     return dummyUser.getId();
                     }
                    
                     public String getVerify()
                     {
                     return verify;
                     }
                    
                     public void setVerify(String verify)
                     {
                     this.verify = verify;
                     }
                    
                     @Destroy
                     @Remove
                     public void destroy()
                     {
                     log.info("dummySeamBean#destroy.. Done!");
                     }
                    
                     public DummyUser getDummyUser()
                     {
                     return dummyUser;
                     }
                    
                     public void setDummyUser(DummyUser dummyUser)
                     {
                     this.dummyUser = dummyUser;
                     }
                    }
                    


                    The Test:

                    package com.ibt.intellidocs.dummy;
                    
                    import org.jboss.seam.mock.BaseSeamTest;
                    import org.jboss.seam.mock.SeamTest;
                    import org.testng.annotations.Test;
                    
                    import java.util.logging.Logger;
                    
                    public class DummyUserActionTest
                     extends SeamTest
                    {
                    
                     Logger log = Logger.getLogger(DummyUserActionTest.class.getName());
                    
                     @Test
                     public void testSeamComponents()
                     throws Exception
                     {
                     new BaseSeamTest.FacesRequest("/dummy/registerDummyUser.xhtml")
                     {
                     @Override
                     protected void invokeApplication()
                     throws Exception
                     {
                     setValue("#{dummyUser.name}", "test1");
                     setValue("#{dummyUser.username}", "test1");
                     setValue("#{dummyUser.password}", "test1");
                     setValue("#{dummyUserAction.verify}", "test1");
                     Object id = invokeAction("#{dummyUserAction.register}");
                     log.info("TEST: Registred User with id: " + id);
                     }
                     }.run();
                    
                     }
                    
                    }