JBoss Embedded and Maven
My current project uses the Embedded Jboss container. If your not familiar with this piece of work, basically, it is an attempt by the Jboss guys to allow your applications targeted to the Jboss container to run within the its own classloader. That means that your EJBs, SEAM components, MDBs etc can be used inside of a standalone application, JUnit tested outside of the Jboss container, or even embedded into another application server (!*&#$*@). Cool, right? Yes, but with some strong words of caution. The Jboss embedded container is still in BETA which means … that its still a bit wabi sabi (to put it gently). Anyhow, its a great idea whose time is finally here. One problem though… being the maven kind of guy, how can I get all my POMs configured so that the embedded container is available without having to copy the 20 Mbs of embedded-ness into each project that I want to use it with? Well, here is the recipe that I put together for your reading pleasure.
Step 1
Grab the latest and the greatest embedded jboss. You can pick up the latest download location from here: http://wiki.jboss.org/wiki/EmbeddedJBoss. Create a maven project to hold all of this code and all of the Jboss Embedded dependencies. Here is a sample:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>your.group.id</groupId> <artifactId>jboss-embedded</artifactId> <name>${project.artifactId}</name> <version>1.0-SNAPSHOT</version> <description> Project encapsulates the Jboss embedded container and any dependencies with the container. </description> <repositories> <repository> <releases> <enabled>true</enabled> <updatePolicy>always</updatePolicy> <checksumPolicy>warn</checksumPolicy> </releases> <snapshots> <enabled>false</enabled> <updatePolicy>never</updatePolicy> <checksumPolicy>fail</checksumPolicy> </snapshots> <id>jboss</id> <name>JBoss Repository</name> <url>http://repository.jboss.com/maven2</url> <layout>default</layout> </repository> </repositories> <dependencies> <dependency> <groupId>org.jboss.embedded</groupId> <artifactId>jboss-embedded-all</artifactId> <version>beta3</version> </dependency> <dependency> <groupId>org.jboss.embedded</groupId> <artifactId>jboss-embedded</artifactId> <version>beta3</version> </dependency> <dependency> <groupId>org.jboss.embedded</groupId> <artifactId>thirdparty-all</artifactId> <version>beta3</version> </dependency> <dependency> <groupId>org.jboss.embedded</groupId> <artifactId>hibernate-all</artifactId> <version>beta3</version> </dependency> </dependencies> </project>
Crack open the Jboss-embedded zip file that you downloaded from sourceforge. Pull out the “bootstrap” folder and copy its contents (not including bootstrap itself) into the src/main/resources directory of this project. At this point, this project is totally configured. Do a mvn install to make it available to other projects that we will need momentarily.
Step 2
Create yourself a parent pom to encapsulate all of the settings that you would like across each project that will use the embedded container. In our world, we have service projects that hold ejb3 components. So it made sense to go ahead and create a service-pom project that can serve as the parent for all “service” projects. I would use the cool import feature, but unfortunately, we need more than just dependencies as you’ll see in a moment. Take a look at the sample POM below.
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>your.group.id</groupId> <artifactId>service-pom</artifactId> <name>${project.artifactId}</name> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging> <description> Encapsulate all the service dependencies and configuration. </description> <repositories> <repository> <releases> <enabled>true</enabled> <updatePolicy>always</updatePolicy> <checksumPolicy>warn</checksumPolicy> </releases> <snapshots> <enabled>false</enabled> <updatePolicy>never</updatePolicy> <checksumPolicy>fail</checksumPolicy> </snapshots> <id>jboss</id> <name>JBoss Repository</name> <url>http://repository.jboss.com/maven2</url> <layout>default</layout> </repository> </repositories> <build> <testResources> <testResource> <directory>target/jboss-embedded</directory> </testResource> </testResources> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin> <plugin> <artifactId>maven-ejb-plugin</artifactId> <configuration> <ejbVersion>3.0</ejbVersion> <archive> <manifest> <addClasspath>true</addClasspath> </manifest> </archive> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>unpack</id> <phase>generate-sources</phase> <goals> <goal>unpack</goal> </goals> <configuration> <artifactItems> <artifactItem> <groupId>your.group.id</groupId> <artifactId> jboss-embedded </artifactId> <type>jar</type> <overWrite>true</overWrite> <outputDirectory> target/jboss-embedded </outputDirectory> </artifactItem> </artifactItems> </configuration> </execution> </executions> </plugin> </plugins> </build> <reporting> <plugins> <plugin> <artifactId>maven-javadoc-plugin</artifactId> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> </plugin> <plugin> <artifactId>maven-clover-plugin</artifactId> </plugin> </plugins> </reporting> <dependencies> <dependency> <groupId>your-group-id</groupId> <artifactId>jboss-embedded</artifactId> <version>1.0-SNAPSHOT</version> <scope>provided</scope> </dependency> </dependencies> </project>
Ok, now this one will need some explaining. There are really 3 important things here. Starting with the most important, declare the dependency on your jboss-embedded project. Number 2, you have to add a reference to the maven-dependency-plugin. Basically what this snippet does, is take the jboss-embedded project from your maven repository, and explode its contents into your target/jboss-embedded directory. Notice how I bound the unpack into the generate-sources phase. This seemed like the most reasonable place to bind it in. Turns out that the embedded container can’t simply bootstrap itself if the configs are encapsulated in a jar file. There might be a way to do this, but I haven’t been able to figure it out. Now to the last important step. You have to add a testResources section to tell maven about the new directory. I chose to put the embedded container in the “target” tree so that when I do a mvn clean, it gets blown away properly.
Final Step
Any project that needs the embedded container functionality now just has to extend from this parent pom and your good to go. Here is a sample pom.
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>your.group.id</groupId> <artifactId>service-pom</artifactId> <version>1.0-SNAPSHOT</version> </parent> <groupId>your.group.id</groupId> <artifactId>really-cool-service</artifactId> <name>${project.artifactId}</name> <version>1.0-SNAPSHOT</version> <packaging>ejb</packaging> <description> Sample Service Implementation </description> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1.1</version> </dependency> </dependencies> </project>
Step for Eclipse people
If your an eclipse user like I am, don’t forget to add target/jboss-embedded to your .classpath file so that your unit tests work from within eclipse.
The Test Case
Just in case your not familiar with what an EJB3 test case looks like using the embedded container, I’ll include a snippet below:
package your.package; import javax.naming.InitialContext; import javax.naming.NamingException; import org.jboss.deployers.spi.DeploymentException; import org.jboss.embedded.Bootstrap; import org.jboss.embedded.junit.BaseTestCase; import org.jboss.virtual.plugins.context.vfs.AssembledContextFactory; import org.jboss.virtual.plugins.context.vfs.AssembledDirectory; import your.package.CoolServiceLocal; import junit.framework.Test; public class CoolServiceTest extends BaseTestCase { private static AssembledDirectory ejbJar; private static AssembledDirectory configSar; public AdjudicationServiceTest() { super("EmbeddedEjb3TestCase"); } public static Test suite() throws Exception { return preProcessedTest(CoolServiceTest.class); } public void testService() throws NamingException { InitialContext ctx = new InitialContext(); CoolServiceLocal local = (CoolServiceLocal) ctx.lookup("CoolService/local"); local.execute(DO_SOMETHING); } public static void deploy() { ejbJar = AssembledContextFactory.getInstance().create("ejbTestCase.jar"); ejbJar.addClass(your.package.CoolService.class); try { Bootstrap.getInstance().deploy(ejbJar); } catch (DeploymentException e) { throw new RuntimeException("Unable to deploy", e); } } public static void undeploy() { try { Bootstrap.getInstance().undeploy(ejbJar); } catch (DeploymentException e) { throw new RuntimeException("Unable to deploy", e); } } }
-
Recent
-
Links
-
Archives
- May 2008 (2)
-
Categories
-
RSS
Entries RSS
Comments RSS