Reputation: 1171
My EntityManager keeps null when using embeddable container. The same code works well when invoked in a regular web application.
Test code:
package com.learning.business.car;
import static org.junit.Assert.assertEquals;
import java.util.List;
import javax.ejb.embeddable.EJBContainer;
import javax.naming.NamingException;
import org.junit.Test;
public class CarRepoTest {
@Test
public void testGetCarsByEjb() throws NamingException {
EJBContainer ec = EJBContainer.createEJBContainer();
CarRepo carRepo = (CarRepo) ec
.getContext()
.lookup("java:global/classes/CarRepo");
List<Car> cars = carRepo.getAll();
assertEquals(0, cars.size());
ec.close();
}
}
While debugging the above code, ec.toString()
shows me:
svContainerActive = true
svNamingInitialized = true
ivContext = com.ibm.ws.naming.java.javaURLContextRoot@fe720e63[super=com.ibm.ws.naming.java.javaURLContextImpl@fe720e63[super=com.ibm.ws.naming.urlbase.UrlContextImpl(java:)@fe720e63[_schemeId=java, _primaryLeafName=null, _strCtxID=ROOT CONTEXT, _ns=com.ibm.ws.naming.ipbase.NameSpace@d2d1a4d7[_nameSpaceName=java:comp(null, null, null), _nameSpaceID=2, _nameSpaceType=1, _contextsTable=java.util.HashMap@c8fb6403[size=2], _bindingsTable=java.util.HashMap@9cd644e1[size=2]]], _javaNameSpaceScope=COMPONENT SCOPE, _jns=javaNameSpaceImpl:{_appName=null,_moduleName=null,_componentName=null,_bootstrapAddress=rir:,_clientMode=ISOLATED,_componentNameSpaceLocation=LOCAL,_otherModuleNames=[],_applicationsRootProviderURL=corbaname:rir:/NameServiceApplicationsRoot#,_applicationRootProviderURL=null,_moduleRootProviderURL=null,_componentRootProviderURL=null,_ns=com.ibm.ws.naming.ipbase.NameSpace@d2d1a4d7[_nameSpaceName=java:comp(null, null, null), _nameSpaceID=2, _nameSpaceType=1, _contextsTable=java.util.HashMap@c8fb6403[size=2], _bindingsTable=java.util.HashMap@9cd644e1[size=2]]}], _caching=false, _rootCache=com.ibm.ws.naming.java.JavaNameSpaceCache@d10b63f9]
ivIsClosed = false
ivModules = [com.ibm.websphere.ejbcontainer.EmbeddableContainer$EmbeddableModule@9202003a[name=classes, file=C:\WorkSpaceRTC\javaee6\target\classes, metadata=com.ibm.ejs.csi.SharedEJBModuleMetaDataImpl@acb40850[embeddable#classes]]]
ivProperties = {enableProtocolSecurity=false}
ivServiceTokens = [sun.misc.Launcher$AppClassLoader@f3ba9f23:interface com.ibm.ws.runtime.service.MetaDataFactoryMgr, sun.misc.Launcher$AppClassLoader@f3ba9f23:interface com.ibm.wsspi.injectionengine.InjectionEngine]
EJB module:
package com.learning.business.car;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
@Stateless
public class CarRepo {
@PersistenceContext
protected EntityManager em;
public List<Car> getAll() {
// "em" keeps null and the below line throws a NullPointerException
TypedQuery<Car> query = em.createQuery("SELECT c FROM Car c", Car.class);
return query.getResultList();
}
}
persistence.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<persistence 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_2_0.xsd"
version="2.0">
<persistence-unit name="javaee6" transaction-type="JTA">
<class>com.learning.business.car.Car</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:test;DB_CLOSE_DELAY=-1" />
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>
</properties>
</persistence-unit>
</persistence>
Exception:
CNTR0020E: EJB threw an unexpected (non-declared) exception during invocation of method "getAll" on bean "BeanId(embeddable#classes#CarRepo, null)". Exception data: java.lang.NullPointerException
at com.learning.business.car.CarRepo.getAll(CarRepo.java:18)
at com.learning.business.car.EJSLocalNSLCarRepo_a1ab5865.getAll(EJSLocalNSLCarRepo_a1ab5865.java)
at com.learning.business.car.CarRepoTest.testGetCarsByEjb(CarRepoTest.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:73)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:46)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46)
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)
On the other hand, the below code works when consumed by a xhtml page in a WebSphere application:
package com.learning.app.car;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import com.learning.business.car.CarRepo;
@ManagedBean
public class CarBean {
@EJB
public CarRepo carRepo;
public Integer getCarsCount() {
// in a WebSphere application it works as expected (EntityManager is correctly injected in CarRepo)
return carRepo.getAll().size();
}
}
Upvotes: 1
Views: 878
Reputation: 18020
It is suggested to include JPA thin client when you use embeddable container. Check the following link for details maybe it will help you Running an embeddable container
When developing an application using JPA in the embeddable EJB container, the class path must include the JPA thin client, com.ibm.ws.jpa.thinclient_n.0.jar, where n is the WebSphere® Application Server release; for example, 8.5 for Version 8.5. The JPA thin client is located in \runtimes where the root directory of the installation image is located.
Upvotes: 2