openejb embedded container cannot find persistence.xml

ejb, jakarta-ee, java, openejb, unit-testing

Solution

I received the same exception and the problem was that two `persistence.xml` were on the classpath of OpenEJB.

When I removed one of them, the problem was solved.

The exception message is not helpful here on part of OpenEJB, but if you debug into `org.apache.openejb.config.Appmodule`'s `hasFailures()` or `hasErrors()` method, you can see more useful info in `EjbModule.getValidation()` calls! (Version 4.0.0).

Problem

I am using openEjb in embedded mode to test a stateless session bean, which has an injected EntityManager. However, when I run the test, it fails because it could not initialize the application. When I see the console I can also see an error related to not being able to find persistence.xml Note: I tried putting WebContent, as well as META-INF in the classpath, but that does not help either. Update: There is something very strange about resource lookups when using openejb + eclipse. - I added WebContent to source folders. I stopped getting the persistence.xml error, but now I get an error which suggests that openejb could not find any managed resource - I added WebContent to source folders, but with a different output folder (using allow output folders for source folders), and the persistence.xml error starts occuring again - I copied META-INF into 'test', which is the source folder for all tests, and everything runs fine - Regarding points 1, and 2, teh issue seems to be the fact that WEB-INF also gets included as part of WebContent. If I exclude WEB-INF, then again openejb can find persistence.xml in the test and the test runs fine I am honestly clueless about what is happening. I am pasting all the relevant errors and code below. Error stack from failing JUnit test in Eclipse ``` org.apache.openejb.OpenEjbContainer$InvalidApplicationException: org.apache.openejb.config.ValidationFailedException: Module failed validation. AppModule(name=) at org.apache.openejb.OpenEjbContainer$Provider.createEJBContainer(OpenEjbContainer.java:273) at javax.ejb.embeddable.EJBContainer.createEJBContainer(EJBContainer.java:56) at javax.ejb.embeddable.EJBContainer.createEJBContainer(EJBContainer.java:43) at com.diycomputerscience.slides.service.SlideServiceTest.setUp(SlideServiceTest.java:45) at junit.framework.TestCase.runBare(TestCase.java:128) at junit.framework.TestResult$1.protect(TestResult.java:106) at junit.framework.TestResult.runProtected(TestResult.java:124) at junit.framework.TestResult.run(TestResult.java:109) at junit.framework.TestCase.run(TestCase.java:120) at junit.framework.TestSuite.runTest(TestSuite.java:230) at junit.framework.TestSuite.run(TestSuite.java:225) at junit.framework.TestSuite.runTest(TestSuite.java:230) at junit.framework.TestSuite.run(TestSuite.java:225) at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) Caused by: org.apache.openejb.config.ValidationFailedException: Module failed validation. AppModule(name=) at org.apache.openejb.config.ReportValidationResults.deploy(ReportValidationResults.java:82) at org.apache.openejb.config.AppInfoBuilder.build(AppInfoBuilder.java:264) at org.apache.openejb.config.ConfigurationFactory.configureApplication(ConfigurationFactory.java:696) at org.apache.openejb.OpenEjbContainer$Provider.createEJBContainer(OpenEjbContainer.java:267) ... 18 more ``` My console output: ``` Apache OpenEJB 4.0.0-beta-2 build: 20120115-08:26 http://openejb.apache.org/ INFO - openejb.home = /home/user/workspace/wwald/slides INFO - openejb.base = /home/user/workspace/wwald/slides INFO - Using 'javax.ejb.embeddable.EJBContainer=true' 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 - Inspecting classpath for applications: 38 urls. Consider adjusting your exclude/include. Current settings: openejb.deployments.classpath.exclude='', openejb.deployments.classpath.include='.*' INFO - Found EjbModule in classpath: /home/user/workspace/wwald/slides/build/classes INFO - Searched 38 classpath urls in 2000 milliseconds. Average 52 milliseconds per url. INFO - Beginning load: /home/user/workspace/wwald/slides/build/classes INFO - Configuring enterprise application: /home/user/workspace/wwald/slides INFO - Configuring Service(id=Default Stateless Container, type=Container, provider-id=Default Stateless Container) INFO - Auto-creating a container for bean SlideService: Container(type=STATELESS, id=Default Stateless Container) INFO - Configuring Service(id=Default Managed Container, type=Container, provider-id=Default Managed Container) INFO - Auto-creating a container for bean com.diycomputerscience.slides.service.SlideServiceTest: Container(type=MANAGED, id=Default Managed Container) INFO - Dumping Generated ejb-jar.xml to: /tmp/ejb-jar-5804778531295096416slides.xml INFO - Dumping Generated openejb-jar.xml to: /tmp/openejb-jar-2921830618491817127slides.xml ERROR - FAIL ... SlideService: Missing required persistence.xml for @PersistenceContext ref "em" to unit "entities" ERROR - Invalid EjbModule(name=slides, path=/home/user/workspace/wwald/slides/build/classes) INFO - Set the 'openejb.validation.output.level' system property to VERBOSE for increased validation details. WARN - configureApplication.loadFailed ``` The Stateless Session Bean: ``` @Stateless public class SlideService { @PersistenceContext(unitName="entities", type=PersistenceContextType.TRANSACTION) private EntityManager em; //various business methods not shown for brevity } ``` persistence.xml ``` <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="entities"> <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider> <jta-data-source>myds</jta-data-source> <non-jta-data-source>myds</non-jta-data-source> <properties> <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema" /> </properties> </persistence-unit> </persistence> ``` The JUnit test case: ``` public class SlideServiceTest extends TestCase { private SlideService slideService; public SlideServiceTest(String name) { super(name); } protected void setUp() throws Exception { super.setUp(); final Properties p = new Properties(); p.put("myds", "new://Resource?type=DataSource"); p.put("myds.JdbcDriver", "org.hsqldb.jdbcDriver"); p.put("myds.JdbcUrl", "jdbc:hsqldb:mem:slidedb"); EJBContainer ejbContainer = EJBContainer.createEJBContainer(); Object oSlideService = ejbContainer.getContext().lookup("java:global/slides/SlideService"); assertNotNull(oSlideService); this.slideService = (SlideService)oSlideService; } //not showing test methods for brevity, since the code fails in setUp itself } ```

Original source