I'm writing this in case other people want to setup Arquillian Persistence Extension with Embedded Weld, JPA, and JTA. See the attached sample.zip on how to do it. Too much to write up here.
The sample contains two test frameworks and a sample app:
- arquillian-jboss7 - which is a remote JBoss 7 AS framework to be used as a comparison/reference
- arquillian-weld - which contains the following:
- Patch for arquillian-weld-ee-embedded-1.1 MockJpaInjectionServices to allow for @PersistenceContext and @PersistenceUnit injection
- Patch for arquillian-persistence-impl PersistenceExtension to mimic the remote container lifecycle but for embedded weld
- InitialContextProducer which loads up a Spring config file to load up datasources and JTA into JNDI. Couldn't think of a better way to initialize JNDI.
- Hibernate as the JPA provider
- JBoss JTA
- config for JBoss 7 AS (src/test/resources/container/jboss7-*)
- config for embedded weld (src/test/resources/container/weld-*, and src/test/resources/spring-jndi.xml)
- Can switch between arquillian-jboss7 and arquillian-weld test frameworks just by changing the dependency in the pom
Also tracking this with https://issues.jboss.org/browse/ARQ-1013
A nice to have would be to create additional producers to setup Hibernate & JBoss JTA so can use a common persistence.xml for JBoss 7 AS and embedded weld.
I encountered some issues with transactions, and included the fixes in the sample.zip attachment. There are a few hacks in place to change the order of the event chain execution so the EntityManagers can be created with transaction support. There is support for JavaArchive and simple WebArchive. There are also so limitations (see below).
Arquillian Weld README:
The goal is to make Arquillian Embedded Weld to behave as close as possible to
JBoss 7 / Hibernate 4 implementation. For everybody else, sorry.
Change PersistenceExtension to support new event chain (org.jboss.arquillian.persistence.client.PersistenceExtension).
The event chain is more like 'org.jboss.arquillian.persistence.container.RemotePersistenceExtension' now:
1. [NEW] InitialContextProducer:
- initializes InitialContext
- jndi.properties points to SpringInitContextFactory, which looks for spring-jndi.xml on the classpath to setup DataSource and JTA.
2. [NEW] PersistenceUnitFactoryProducer
- scans for persistence.xml and creates EntityManagerFactory(ies), which registers all the entities.
- there are limitations (see below)
3. [NO CHANGE] All the Arquillian Persistence events
- Create transaction
- Load DbUnit data
4. [UPDATE] TestInstanceEnricher:
- change precedence to execute after PersistenceTestTrigger
- this allows for EntityManagers to be created with a transaction setup by Arquillian Persistence
1. The PersistenceUnitInfo's root URL ideally should be the ShrinkWrap URL (archive:/...). However this URL protocol isn't recognized by JPA implementations and will cause exceptions. Need to convert 'archive:' URL protocol into a more recognized protocol. See: org.hibernate.ejb.packaging.JarVisitorFactory.getVisitor(). For the time being, use file://.../target/classes as the PU root url.
2. Implement missing PersistenceUnitInfo methods:
- getJarFileUrls(): Currently returns empty list as there is no support for <persistence-unit>/<jar-file>
- addTransformer(): Currently do not set 'hibernate.ejb.use_class_enhancer'
- getNewTempClassLoader(): Currently returns null. Works by reports no compliant with spec.
3. If WAR, load persistence found in jars in WEB-INF/lib.
- Need to find jars using ClassLoader, or is there a better way?
4. Add EAR support.
5. Look at org.jboss.as:jboss-as-jpa for more info to improve this hack job. Specifically for WAR and EAR support.
6. Only compatible with Hibernate 4. See: org.jboss.arquillian.container.weld.ee.embedded_1_1.mock.jpa.PersistenceUnitFactory
sample.zip 31.9 KB