As I stated here I see three levels of using Maven2 to build and deploy your EJB3 application with JBoss5 as application server. The minimal use of Maven I have described here, in this post I will extend the role of Maven so you can use it for the deployment of the JEE application too. I will also show how to create a client class in Netbeans to test your deployment. To show this I will extend the example I used in the previous post.
To make use of Maven for the deployment I added a new module to my project: jboss-ear. With this module I will create an ear file for the ch4 module and use this plugin to deploy the ear to JBoss (I wasn’t able to deploy the ejb-jar directly with the plugin so hence the extra module). The module is very basic and only contains a pom file:
<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>net.pascalalma.jboss</groupId> <artifactId>jboss-ear</artifactId> <packaging>ear</packaging> <version>1.0-SNAPSHOT</version> <name>jboss-ear</name> <dependencies> <dependency> <groupId>net.pascalalma.jboss</groupId> <artifactId>ch4</artifactId> <type>ejb</type> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-ear-plugin</artifactId> <configuration> <displayName>Ch4 Services</displayName> <description>All EJBs for a chapter</description> <version>1.4</version> <modules> <ejbModule> <groupId>net.pascalalma.jboss</groupId> <artifactId>ch4</artifactId> </ejbModule> </modules> </configuration> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>jboss-maven-plugin</artifactId> <configuration> <jbossHome>${jboss.home}</jbossHome> <serverName>default</serverName> <port>8080</port> </configuration> </plugin> </plugins> <finalName>${artifactId}</finalName> </build> </project>
With this in place you can do the following to deploy the ear file:
mvn package jboss:harddeploy
The result in JBoss will be something like:
15:47:43,340 INFO [SessionSpecContainer] Stopping jboss.j2ee:ear=jboss-ear.ear,jar=ch4-1.0-SNAPSHOT.jar,name=TravelAgentBean,service=EJB3
15:47:43,365 INFO [EJBContainer] STOPPED EJB: com.titan.travelagent.TravelAgentBean ejbName: TravelAgentBean
15:47:43,414 INFO [PersistenceUnitDeployment] Stopping persistence unit persistence.unit:unitName=jboss-ear.ear/ch4-1.0-SNAPSHOT.jar#titan
15:47:43,414 INFO [SessionFactoryImpl] closing
15:47:43,414 INFO [SchemaExport] Running hbm2ddl schema export
15:47:43,415 INFO [SchemaExport] exporting generated schema to database
15:47:43,416 INFO [SchemaExport] schema export complete
15:47:43,416 INFO [SessionFactoryObjectFactory] Unbinding factory from JNDI name: persistence.unit:unitName=jboss-ear.ear/ch4-1.0-SNAPSHOT.jar#titan
15:47:43,416 INFO [NamingHelper] JNDI InitialContext properties:{java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory, java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces}
15:47:43,416 INFO [SessionFactoryObjectFactory] Unbound factory from JNDI name: persistence.unit:unitName=jboss-ear.ear/ch4-1.0-SNAPSHOT.jar#titan
Now to test this EJB bean with a client running in Netbeans I had some more trouble. It appears you can not have a ‘static void main(String[] args)’ method to be executed if you have put your client class in a Maven project. In a Maven project the ‘run file’ command from Netbeans will always lead to a ‘mvn test’ command for the corresponding file. The way I work around this, is by making the test client, provided by the book, a jUnit test class, but without the phrase ‘test’ in the classname. By doing it this way, the client class is not picked up when building the project with Maven (which is good because it would be too early to test it because the class has to be deployed first on our JBoss instance). However, the test is executed when performing a ‘run file’ in Netbeans! Here is my code for the Client:
package com.titan.clients; import com.titan.travelagent.TravelAgentRemote; import com.titan.domain.Cabin; import javax.naming.Context; import javax.naming.InitialContext; import org.junit.Test; public class Client { private Context jndiContext = null; @Test public void mainTest() throws Exception { try { jndiContext = getInitialContext(); String jndiName = "jboss-ear/TravelAgentBean/remote"; Object ref = jndiContext.lookup(jndiName); TravelAgentRemote dao = (TravelAgentRemote) ref; Cabin cabin_1 = new Cabin(); cabin_1.setId(1); cabin_1.setName("Master Suite"); cabin_1.setDeckLevel(1); cabin_1.setShipId(1); cabin_1.setBedCount(3); dao.createCabin(cabin_1); Cabin cabin_2 = dao.findCabin(1); System.out.println(cabin_2.getName()); System.out.println(cabin_2.getDeckLevel()); System.out.println(cabin_2.getShipId()); System.out.println(cabin_2.getBedCount()); } catch (javax.naming.NamingException ne) { ne.printStackTrace(); } } public static Context getInitialContext() throws javax.naming.NamingException { return new InitialContext(); } }
Please note that I had to modify the jndi name for looking up my EJB component. This is caused by the fact that JBoss adds the name of the ear file with which the EJB component is deployed.
Anyway, here is the produced output of the test class:
——————————————————-
T E S T S
——————————————————-
Running com.titan.clients.Client
Master Suite
1
1
3Results :
————————————————————————
BUILD SUCCESSFUL
————————————————————————
Total time: 3 seconds
Finished at: Sun May 03 16:22:03 CEST 2009
Final Memory: 7M/13M
————————————————————————
By the way, the added ear-module can be reused for the EJB3 modules of the other chapters. Just modify the dependencies in the ear file and redeploy the constructed ear-file.