Running AS7 embedded in Arquillian
thomas.diesler Nov 22, 2010 8:40 AMThis post describes what I have done and seen when running AS7 embedded in Arquillian. There is a large overlap with what Kabir has done with embedded AS7 so lets try to converge.
The JBossASEmbeddedContainer the StandaloneServerFactory and waits for the Arquillian MBean to become available
Properties sysprops = new Properties();
sysprops.putAll(System.getProperties());
sysprops.setProperty("jboss.home.dir", jbossHomeDir.getAbsolutePath());
sysprops.setProperty("java.util.logging.manager", "org.jboss.logmanager.LogManager");
sysprops.setProperty("logging.configuration", "file:" + jbossHomeDir + "/standalone/configuration/logging.properties");
sysprops.setProperty("org.jboss.boot.log.file", jbossHomeDir + "/standalone/log/boot.log");
server = StandaloneServerFactory.create(jbossHomeDir, sysprops);
server.start();
The StandaloneServerFactory uses the InitialModuleLoaderFactory to bootstrap modules with a controlled set of packages from the app classpath. I agree with Jason, it is impossible to put stuff on the appclasspath and somehow hope the test deployemnts will behave like they would in a running server.
For this to work in ARQ it is necessary that nothing initializes jdk logging before we have a chance to load the LoggingManager from the "org.jboss.logmanager" module. Therefore, I added a looging abstraction to ARQ that allows you do disable or redirect ARQ logging to System.out
<plugin> <artifactId>maven-surefire-plugin</artifactId> <configuration> <systemProperties> <property> <name>java.util.logging.manager</name> <value>org.jboss.logmanager.LogManager</value> </property> <property> <name>arquillian.logging</name> <value>system</value> </property> </systemProperties> </configuration> </plugin>
The StandaloneServerFactory loads the server module and uses reflection and a proxy to bootstrap the server.
Currently, the server comes up and deployment fails with
12:46:07,295 ERROR [org.jboss.as.protocol.connection] (pool-1-thread-2) Failed to read a message: java.util.ServiceConfigurationError: org.jboss.marshalling.ProviderDescriptor: Provider org.jboss.marshalling.river.RiverProviderDescriptor could not be instantiated: java.lang.ClassCastException at java.util.ServiceLoader.fail(ServiceLoader.java:207) [:1.6.0_21] at java.util.ServiceLoader.access$100(ServiceLoader.java:164) [:1.6.0_21] at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:353) [:1.6.0_21] at java.util.ServiceLoader$1.next(ServiceLoader.java:421) [:1.6.0_21] at org.jboss.marshalling.Marshalling.loadMarshallerFactory(Marshalling.java:78) [jboss-marshalling-1.3.0.CR8.jar:1.3.0.CR8] at org.jboss.marshalling.Marshalling.getMarshallerFactory(Marshalling.java:74) [jboss-marshalling-1.3.0.CR8.jar:1.3.0.CR8] at org.jboss.as.protocol.ProtocolUtils.<clinit>(ProtocolUtils.java:50) [jboss-as-protocol-7.0.0.Alpha1.jar:7.0.0.Alpha1] at org.jboss.as.protocol.mgmt.ManagementProtocolHeader.read(ManagementProtocolHeader.java:75) [jboss-as-protocol-7.0.0.Alpha1.jar:7.0.0.Alpha1] at org.jboss.as.protocol.mgmt.ManagementResponseHeader.read(ManagementResponseHeader.java:60) [jboss-as-protocol-7.0.0.Alpha1.jar:7.0.0.Alpha1] at org.jboss.as.protocol.mgmt.ManagementProtocolHeader.<init>(ManagementProtocolHeader.java:55) [jboss-as-protocol-7.0.0.Alpha1.jar:7.0.0.Alpha1] at org.jboss.as.protocol.mgmt.ManagementResponseHeader.<init>(ManagementResponseHeader.java:45) [jboss-as-protocol-7.0.0.Alpha1.jar:7.0.0.Alpha1] at org.jboss.as.protocol.mgmt.ManagementRequest$1.handle(ManagementRequest.java:124) [jboss-as-protocol-7.0.0.Alpha1.jar:7.0.0.Alpha1]
StandaloneServer is now an interface that also supports StandaloneServer.stop(). The idea is that the factory installs a service that can be used to bring down the server.
An AS7 Arquinllian test would look like this
@RunWith(Arquillian.class) public class JBossASEmbeddedIntegrationTestCase { @Inject public ServiceContainer container; @Deployment public static JavaArchive createDeployment() throws Exception { JavaArchive archive = ShrinkWrap.create(JavaArchive.class, "test.jar"); archive.addClasses(SimpleServiceActivator.class); String path = "META-INF/services/" + ServiceActivator.class.getName(); URL resourceURL = JBossASEmbeddedIntegrationTestCase.class.getResource("/module/" + path); archive.addResource(new File(resourceURL.getFile()), path); return archive; } @Test public void testDeployedService() throws Exception { assertNotNull("ServiceContainer not null", container); ServiceController<?> controller = container.getRequiredService(SimpleService.SERVICE_NAME); SimpleService service = (SimpleService)controller.getValue(); service.add(2, 3); } }
The ServiceContainer is injected by the ServiceContainerEnricher. The test is deployed using the ServerDeploymentManager, which is part of the domain protocol.
To try this out you need to checkout these branches
https://github.com/jbosgi/arquillian/tree/jbas7
https://github.com/jbosgi/jboss-as/tree/arquillian
Build AS7 and in arquillian run
mvn -Djboss.home=/home/tdiesler/git/jboss-as/build/target/jboss-7.0.0.Alpha2 -pl container/jbossas-embedded-7 -am install
I'll talk this through with Kabir. So hopefully the demos and other smoke/integration tests can be embedded ARQ tests soon.
cheers
-thomas