I'm trying to embed OpenEJB 3.1 in my EJB3 application so that I can unit test my application. If it matters, I'm using NetBeans 6.5.
I followed the following instructions to setup Toplink Essentials as my OpenEJB persistence provider: http://qbeukes.blogspot.com/2008/08/toplink-as-your-openejb-persistence.html I removed the line of code that sets up toplink.target-server since OpenEJB 3.1 sets this up automatically. Additionally, I had to set the java.naming.factory.initial system factory: System.getProperties().setProperty("java.naming.factory.initial", "org.apache.openejb.client.LocalInitialContextFactory"); My problem: When I go to run my JUnit test on my Stateless EJB that is deployed within OpenEJB, everything goes fine until I try to persist an object from within the EJB method that is under test. I get a javax.naming.NameNotFoundException: Name "myDataSource" not found. myDataSource is the name of my data source from my persistence.xml, which is the same data source name that I used when setting up my InitialContext in my test code. It looks to me like the container is trying to inject a different myDataSource than the one that I created when setting up the InitialContext. See test results (with stack trace), source code, and XML files below. Any help is greatly appreciated! aflyctus /*********************************************** * Here's the NetBeans output with stack trace ***********************************************/ ------------- Standard Output --------------- Apache OpenEJB 3.1 build: 20081009-03:31 http://openejb.apache.org/ INFO - openejb.home = /home/aflyctus/netbeans-example/OpenEJBTest/modules/my INFO - openejb.base = /home/aflyctus/netbeans-example/OpenEJBTest/modules/my INFO - Configuring Service(id=Default Security Service, type=SecurityService, provider-id=Default Security Service) INFO - Configuring Service(id=Default Transaction Manager, type=TransactionManager, provider-id=Default Transaction Manager) INFO - Configuring Service(id=myDataSource, type=Resource, provider-id=Default JDBC Database) INFO - Found EjbModule in classpath: /home/aflyctus/netbeans-example/OpenEJBTest/modules/my/build/jar INFO - Beginning load: /home/aflyctus/netbeans-example/OpenEJBTest/modules/my/build/jar INFO - Configuring enterprise application: classpath.ear INFO - Configuring Service(id=Default Stateless Container, type=Container, provider-id=Default Stateless Container) INFO - Auto-creating a container for bean MyEJBBean: Container(type=STATELESS, id=Default Stateless Container) INFO - Configuring PersistenceUnit(name=myPU, provider=oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider) INFO - Auto-creating a Resource with id 'myDataSourceNonJta' of type 'DataSource for 'myPU'. INFO - Configuring Service(id=myDataSourceNonJta, type=Resource, provider-id=myDataSource) INFO - Adjusting myPU <non-jta-data-source> to 'myDataSourceNonJta' INFO - Enterprise application "classpath.ear" loaded. INFO - Assembling app: classpath.ear INFO - PersistenceUnit(name=myPU, provider=oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider) INFO - Jndi(name=MyEJBBeanLocal) --> Ejb(deployment-id=MyEJBBean) INFO - Created Ejb(deployment-id=MyEJBBean, ejb-name=MyEJBBean, container=Default Stateless Container) INFO - Deployed Application(path=classpath.ear) ------------- ---------------- --------------- Testcase: testMyMethod(mypackage.test.MyEJBTest): Caused an ERROR The bean encountered a non-application exception; nested exception is: javax.persistence.PersistenceException: Exception [TOPLINK-7060] (Oracle TopLink Essentials - 2.0.1 (Build b09d-fcs (12/06/2007))): oracle.toplink.essentials.exceptions.ValidationException Exception Description: Cannot acquire data source [myDataSource]. Internal Exception: javax.naming.NameNotFoundException: Name "myDataSource" not found. javax.ejb.EJBException: The bean encountered a non-application exception; nested exception is: javax.persistence.PersistenceException: Exception [TOPLINK-7060] (Oracle TopLink Essentials - 2.0.1 (Build b09d-fcs (12/06/2007))): oracle.toplink.essentials.exceptions.ValidationException Exception Description: Cannot acquire data source [myDataSource]. Internal Exception: javax.naming.NameNotFoundException: Name "myDataSource" not found. at org.apache.openejb.core.ivm.BaseEjbProxyHandler.convertException(BaseEjbProxyHandler.java:363) at org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke(BaseEjbProxyHandler.java:291) at $Proxy25.myMethod(Unknown Source) at mypackage.test.MyEJBTest.testMyMethod(MyEJBTest.java:81) Caused by: javax.persistence.PersistenceException: Exception [TOPLINK-7060] (Oracle TopLink Essentials - 2.0.1 (Build b09d-fcs (12/06/2007))): oracle.toplink.essentials.exceptions.ValidationException Exception Description: Cannot acquire data source [myDataSource]. Internal Exception: javax.naming.NameNotFoundException: Name "myDataSource" not found. at oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:239) at oracle.toplink.essentials.internal.ejb.cmp3.base.EntityManagerFactoryImpl.getServerSession(EntityManagerFactoryImpl.java:93) at oracle.toplink.essentials.internal.ejb.cmp3.base.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:126) at oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:99) at org.apache.openejb.persistence.JtaEntityManagerRegistry.getEntityManager(JtaEntityManagerRegistry.java:105) at org.apache.openejb.persistence.JtaEntityManager.getEntityManager(JtaEntityManager.java:61) at org.apache.openejb.persistence.JtaEntityManager.persist(JtaEntityManager.java:97) at mypackage.MyEJBBean.myMethod(MyEJBBean.java:20) at org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke(ReflectionInvocationContext.java:158) at org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed(ReflectionInvocationContext.java:141) at org.apache.openejb.core.interceptor.InterceptorStack.invoke(InterceptorStack.java:67) at org.apache.openejb.core.stateless.StatelessContainer._invoke(StatelessContainer.java:211) at org.apache.openejb.core.stateless.StatelessContainer.invoke(StatelessContainer.java:169) at org.apache.openejb.core.ivm.EjbObjectProxyHandler.businessMethod(EjbObjectProxyHandler.java:217) at org.apache.openejb.core.ivm.EjbObjectProxyHandler._invoke(EjbObjectProxyHandler.java:77) at org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke(BaseEjbProxyHandler.java:286) Caused by: Exception [TOPLINK-7060] (Oracle TopLink Essentials - 2.0.1 (Build b09d-fcs (12/06/2007))): oracle.toplink.essentials.exceptions.ValidationException Exception Description: Cannot acquire data source [myDataSource]. Internal Exception: javax.naming.NameNotFoundException: Name "myDataSource" not found. at oracle.toplink.essentials.exceptions.ValidationException.cannotAcquireDataSource(ValidationException.java:373) at oracle.toplink.essentials.jndi.JNDIConnector.connect(JNDIConnector.java:135) at oracle.toplink.essentials.sessions.DatasourceLogin.connectToDatasource(DatasourceLogin.java:184) at oracle.toplink.essentials.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:582) at oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:280) at oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:229) Caused by: javax.naming.NameNotFoundException: Name "myDataSource" not found. at org.apache.openejb.core.ivm.naming.IvmContext.federate(IvmContext.java:172) at org.apache.openejb.core.ivm.naming.IvmContext.lookup(IvmContext.java:129) at org.apache.openejb.core.ivm.naming.IvmContext.lookup(IvmContext.java:257) at org.apache.openejb.core.ivm.naming.ContextWrapper.lookup(ContextWrapper.java:111) at javax.naming.InitialContext.lookup(InitialContext.java:396) at oracle.toplink.essentials.jndi.JNDIConnector.connect(JNDIConnector.java:129) Test mypackage.test.MyEJBTest FAILED /home/aflyctus/netbeans-example/OpenEJBTest/modules/my/nbproject/build-impl.xml:526: Some tests failed; see details above. BUILD FAILED (total time: 2 seconds) /****************************** * Here's the test code ******************************/ package mypackage.test; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Before; import org.junit.After; import org.junit.Test; import java.util.Properties; import javax.naming.InitialContext; import javax.naming.Context; import javax.naming.NamingException; import mypackage.MyEJBLocal; public class MyEJBTest { private static InitialContext initialContext; private MyEJBLocal instance; public MyEJBTest() { } @BeforeClass public static void setUpClass() throws Exception { //Init the OpenEJB Container try { Properties properties = new Properties(); properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client. LocalInitialContextFactory"); properties.put("myDataSource", "new://Resource?type=DataSource"); properties.put("myDataSource.JdbcDriver", "oracle.jdbc.OracleDriver"); properties.put("myDataSource.JdbcUrl", "jdbc:oracle:thin:@//localhost:1521/xe"); properties.put("myDataSource.UserName", "dbuser"); properties.put("myDataSource.Password", "dbuser"); System.getProperties().setProperty("toplink.ddl-generation", "drop-and-create-tables"); System.getProperties().setProperty("toplink.logging.level", "INFO"); System.getProperties(). setProperty("toplink.create-ddl-jdbc-file-name", create.sql"); System.getProperties(). setProperty("toplink.ddl-generation.output-mode", "both"); System.getProperties(). setProperty("java.naming.factory.initial", "org.apache.openejb.client.LocalInitialContextFactory"); initialContext = new InitialContext(properties); } catch (NamingException ex) { System.err.println(ex.getMessage()); } } @AfterClass public static void tearDownClass() throws Exception { } @Before public void setUp() throws Exception { instance = (MyEJBLocal) initialContext.lookup("MyEJBBeanLocal"); } @After public void tearDown() { } @Test public void testMyMethod() { instance.myMethod(); } } /************************************ * EJB implementation code ************************************/ package mypackage; import javax.ejb.Stateless; import javax.persistence.PersistenceContext; import javax.persistence.EntityManager; import javax.ejb.TransactionAttribute; import static javax.ejb.TransactionAttributeType.*; @Stateless public class MyEJBBean implements MyEJBLocal { @PersistenceContext(unitName="myPU") private EntityManager entityManager; @TransactionAttribute(REQUIRED) public void myMethod() { MyEntity myEntity = new MyEntity(); entityManager.persist(myEntity); } } /************************************ * Entity class ************************************/ package mypackage; import java.io.Serializable; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Entity public class MyEntity implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator="MY_ID_SEQUENCE") private Long id; public Long getId() { return id; } public void setId(Long id) { this.id = id; } @Override public int hashCode() { int hash = 0; hash += (id != null ? id.hashCode() : 0); return hash; } @Override public boolean equals(Object object) { // TODO: Warning - this method won't work in the case the id fields are not set if (!(object instanceof MyEntity)) return false; MyEntity other = (MyEntity) object; if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) return false; return true; } @Override public String toString() { return "mypackage.MyEntity[id=" + id + "]"; } } /********************************* * ejb-jar.xml *********************************/ <?xml version="1.0" encoding="UTF-8"?> <ejb-jar xmlns = "http://java.sun.com/xml/ns/javaee" version = "3.0" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd"> </ejb-jar> /********************************** * persistence.xml **********************************/ <?xml version="1.0" encoding="UTF-8"?> <persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> <persistence-unit name="myPU" transaction-type="JTA"> <provider>oracle.toplink.essentials.PersistenceProvider</provider> <jta-data-source>myDataSource</jta-data-source> <properties> <property name="toplink.ddl-generation" value="create-tables"/> </properties> </persistence-unit> </persistence>
