Testing persistence EJB with arquillian in multimodule maven projects
dgmora Oct 2, 2012 9:58 AMI want to use Arquillian to be able to access the database while using JUnit tests. I have been able to access to an EntityManager, but I need to to something more complex.
The project has several modules and is packaged as a ear.
- In ModuleA I have a Local and Remote interface of an EJB, which access to the database with an EntityManager.
public interface PersistenceLocal {
public <T> T insert(T object);
//....
}
- In ModuleB I have one class that implements both of these interfaces
@Stateless
@Local(ProcessServiceLocal.class)
@Remote(ProcessServiceRemote.class)
public class PersistenceImpl implements ProcessServiceRemote, ProcessServiceRemote{
@PersistenceContext(unitName = PERSISTENCE_UNIT)
private EntityManager entityManager;
public <T> T insert(T object) {
entityManager.persist(object);
entityManager.flush();
return object;
}
//....
}
- ModuleB depends on ModuleA via Maven
- I'm trying to access the database in a test in ModuleC. This module depends via Maven on ModuleA and ModuleB with scope provided.
.
@RunWith(Arquillian.class)
public class testTest {
@Deployment
public static Archive<?> createDeployment() {
File modA = Maven.resolver().resolve("group.id:modA:0.1")
.withTransitivity().asSingle(File.class);
File modB = Maven.resolver().resolve("group.id:modB:0.1")
.withTransitivity().asSingle(File.class);
//not sure of this step, but I'm just adding some libs.
//If I don't add somewhere the test I have some
//error bc it cannot be found
JavaArchive test = ShrinkWrap.create(
JavaArchive.class, "sth.jar").addClass(testTest.class);
EnterpriseArchive ear = ShrinkWrap.create(EnterpriseArchive.class,"test.ear")
.addAsLibrary(api)
.addAsModule(test)
.addAsModule(ejb);
return ear;
}
@EJB
PersistenceLocal persistence;
@Test
public void testPersistance() {
Assert.assertNotNull(persistence);
}
}
The ear deployed with this config is the following:
All three modules are packaged as jars inside the ear, but ModuleA is inside the lib folder of the ear. I am using arquillian with a remote JBoss 7.0.1. arquillian.xml and persistence.xml are correctly set up, as I can access with EntityManager.
What I don't know is what should I add to the packaging in order to make it work. I'm really struggling with this, because I am not sure which is the problem, since all the classes are in different modules and I'm new to Arquillian.
Error I get right now is:
org.jboss.arquillian.container.spi.client.container.DeploymentException: Could not deploy to container
Caused by: java.lang.Exception: {
"Failed services" => {"jboss.deployment.subunit.\"test.ear\".\"modB-357922373339836768.jar\".POST_MODULE" => "org.jboss.msc.service.StartException in service jboss.deployment.subunit.\"test.ear\".\"modB-357922373339836768.jar\".POST_MODULE: Failed to process phase POST_MODULE of subdeployment \"modB-357922373339836768.jar\" of deployment \"test.ear\""},
"Services with missing/unavailable dependencies" => [
"jboss.naming.context.java.comp.test.test.test.ValidatorFactory missing [ jboss.naming.context.java.module.test.test ]",
"jboss.naming.context.java.comp.test.test.test.Validator missing [ jboss.naming.context.java.module.test.test ]"
]
}
And looking into the server log:
Caused by: org.jboss.as.server.deployment.DeploymentUnitProcessingException: Could not load EJB class group.id.ejb.persistence.impl.persistenceImpl
at org.jboss.as.ejb3.deployment.processors.BusinessViewAnnotationProcessor.getEjbClass(BusinessViewAnnotationProcessor.java:197)
at org.jboss.as.ejb3.deployment.processors.BusinessViewAnnotationProcessor.deploy(BusinessViewAnnotationProcessor.java:77)
at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:115)
... 5 more
Caused by: java.lang.ClassNotFoundException: group.id.ejb.persistence.impl.persistenceImpl from [Module "deployment.test.ear.modB-6953783656278818077.jar:main" from Service Module Loader]
at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:191)
at org.jboss.modules.ConcurrentClassLoader.performLoadClassChecked(ConcurrentClassLoader.java:358)
at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:307)
at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:101)
at org.jboss.as.ejb3.deployment.processors.BusinessViewAnnotationProcessor.getEjbClass(BusinessViewAnnotationProcessor.java:195)
... 7 more
I looked on the temporal jar generated (which ends up stored somewhere on the disk) and the persistenceImpl.class is correctly located in the jar. Maybe some classloading isolation issue?
Content of the ear generated by Shrinkwrap:
[context=/test.jar]
[context=/lib/modA.jar]
[context=/modB.jar]
I have looked inside the jar, and maybe there is some issue with the slashes and backslashes mix?
BasicPath [context=/group\id\ejb\persistence\impl\PersistenceImpl.class]