Start a Java EE application with Maven
September 07, 2009 20:44:15 Last update: November 03, 2011 14:43:19
Step 1: Repackage a web app as EAR
A Java EE application is a multimodule Maven project. At the very least you'll need to package a WAR and an EAR. To get started, I'll simply re-package the simple webapp as an EAR.
Step 2: Add an EJB
A Java EE application is a multimodule Maven project. At the very least you'll need to package a WAR and an EAR. To get started, I'll simply re-package the simple webapp as an EAR.
- Create a directory named
javaee-app
- Copy the webapp from here to
javaee-app
. Renamestruts1app
towebapp
.
- Create pom.xml under
javaee-app
:<project> <modelVersion>4.0.0</modelVersion> <groupId>maven-tutorial</groupId> <version>1.0</version> <artifactId>java-ee</artifactId> <packaging>pom</packaging> <name>Java EE Example</name> <modules> <module>ear</module> <module>webapp</module> </modules> </project>
- Create a directory named
ear
underjavaee-app
. Createpom.xml
underear
:<project> <modelVersion>4.0.0</modelVersion> <groupId>maven-tutorial.java-ee</groupId> <artifactId>ear</artifactId> <packaging>ear</packaging> <version>1.0</version> <name>Java EE EAR Example</name> <parent> <groupId>maven-tutorial</groupId> <artifactId>java-ee</artifactId> <version>1.0</version> </parent> <dependencies> <dependency> <groupId>maven-tutorial.java-ee</groupId> <artifactId>webapp</artifactId> <version>1.0</version> <type>war</type> </dependency> </dependencies> </project>
- Modify
pom.xml
in thewebapp
directory so that it looks like this:<project> <modelVersion>4.0.0</modelVersion> <groupId>maven-tutorial.java-ee</groupId> <artifactId>webapp</artifactId> <packaging>war</packaging> <version>1.0</version> <name>Java EE webapp</name> <parent> <groupId>maven-tutorial</groupId> <artifactId>java-ee</artifactId> <version>1.0</version> </parent> <dependencies> <dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifactId> <version>6.0-SNAPSHOT</version> <scope>provided</scope> </dependency> <dependency> <groupId>struts</groupId> <artifactId>struts</artifactId> <version>1.2.9</version> </dependency> </dependencies> </project>
- Build with "
mvn package
" in thejavaee-app
directory. You can see thatear-1.0.ear
is successfully generated injavaee-app/ear/target
.
Maven successfully resolves dependencies between the sub-projects. However, if you run "mvn package
" from insidejavaee-app/ear
, the dependency onwebapp
cannot be resolved!
- As part of the packaging process, Maven generates
application.xml
with default values for application "display name" and web context root, etc. You can add the following section tojavaee-app/ear/pom.xml
to change the values:<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-ear-plugin</artifactId> <configuration> <displayName>Java EE Application</displayName> <modules> <webModule> <groupId>maven-tutorial.java-ee</groupId> <artifactId>webapp</artifactId> <contextRoot>/the-context-root</contextRoot> </webModule> </modules> </configuration> </plugin> </plugins> </build>
More details are available from http://maven.apache.org/plugins/maven-ear-plugin/.
Alternatively, you can create directoryjavaee-app/ear/src/main/application/META-INF
and put your customapplication.xml
file there.
Step 2: Add an EJB
- Create a new directory named
ejb
underjavaee-app
. Createpom.xml
underear
:<project> <modelVersion>4.0.0</modelVersion> <groupId>maven-tutorial.java-ee</groupId> <artifactId>ejb</artifactId> <packaging>ejb</packaging> <version>1.0</version> <name>Java EE ejb</name> <parent> <groupId>maven-tutorial</groupId> <artifactId>java-ee</artifactId> <version>1.0</version> </parent> </project>
- Create directory
src/main/java/org/xinotes/ejb
underjavaee-app
. Create a stateless session bean interface and implementation under the newly created directory:
Hello.javapackage org.xinotes.ejb; public interface Hello { public String sayHello(String name); }
HelloBean.javapackage org.xinotes.ejb; import javax.ejb.Stateless; import javax.ejb.Local; @Stateless @Local({Hello.class}) public class HelloBean implements Hello { public HelloBean() { } public String sayHello(String name) { return "Hello " + name + "!"; } }
- Modify the
pom.xml
underjavaee-app
to include the EJB module (note that I also moved the Java EE API dependency here and added some options for the compiler and ejb plugins):<project> <modelVersion>4.0.0</modelVersion> <groupId>maven-tutorial</groupId> <version>1.0</version> <artifactId>java-ee</artifactId> <packaging>pom</packaging> <name>Java EE pom</name> <modules> <module>ear</module> <module>webapp</module> <module>ejb</module> </modules> <dependencies> <dependency> <groupId>javaee</groupId> <artifactId>javaee-api</artifactId> <version>5</version> <scope>provided</scope> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-ejb-plugin</artifactId> <configuration> <ejbVersion>3.0</ejbVersion> </configuration> </plugin> </plugins> </build> </project>
- Add the
ejb
as a dependency for theear
(pom.xml
underjavaee-app/ear
):<project> <modelVersion>4.0.0</modelVersion> <groupId>maven-tutorial.java-ee</groupId> <artifactId>ear</artifactId> <packaging>ear</packaging> <version>1.0</version> <name>Java EE ear</name> <parent> <groupId>maven-tutorial</groupId> <artifactId>java-ee</artifactId> <version>1.0</version> </parent> <dependencies> <dependency> <groupId>maven-tutorial.java-ee</groupId> <artifactId>webapp</artifactId> <version>1.0</version> <type>war</type> </dependency> <dependency> <groupId>maven-tutorial.java-ee</groupId> <artifactId>ejb</artifactId> <version>1.0</version> <type>ejb</type> </dependency> </dependencies> </project>
- Add the
ejb
as a dependency for thewebapp
(pom.xml
underjavaee-app/webapp
):<project> <modelVersion>4.0.0</modelVersion> <groupId>maven-tutorial.java-ee</groupId> <artifactId>webapp</artifactId> <packaging>war</packaging> <version>1.0</version> <name>Java EE webapp</name> <parent> <groupId>maven-tutorial</groupId> <artifactId>java-ee</artifactId> <version>1.0</version> </parent> <dependencies> <dependency> <groupId>maven-tutorial.java-ee</groupId> <artifactId>ejb</artifactId> <version>1.0</version> <type>ejb</type> </dependency> <dependency> <groupId>struts</groupId> <artifactId>struts</artifactId> <version>1.2.9</version> </dependency> </dependencies> </project>
- Modify the struts action (under
webapp/src/main/java/org/xinotes/
) to make use of the stateless session bean:
HelloAction.javapackage org.xinotes; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.ejb.EJB; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import org.apache.struts.action.*; import org.xinotes.ejb.Hello; public class HelloAction extends Action { Hello helloEjb; public HelloAction() throws NamingException { Context ctx = new InitialContext(); helloEjb = (Hello) ctx.lookup("HelloBeanLocal"); } public ActionForward execute(ActionMapping map, ActionForm form, HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { HelloForm f = (HelloForm) form; String message = helloEjb.sayHello(f.getName()); req.setAttribute("message", message); return map.findForward("hello"); } }
- Build with "
mvn package
" in thejavaee-app
directory.
- Note that the struts action code above assumes that the JNDI name for the
Hello
bean isHelloBeanLocal
. You may need to add a proprietary deployment descriptor to bind the EJB to that name. Simply create the directoryejb/src/main/resources/META-INF
and put the deployment descriptor there. For OC4J the file isorion-ejb-jar.xml
, and here's the content:<?xml version="1.0" encoding="utf-8"?> <orion-ejb-jar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://xmlns.oracle.com/oracleas/schema/orion-ejb-jar-10_0.xsd" deployment-version="10.1.3.3.0" deployment-time="123d598f9ca" schema-major-version="10" schema-minor-version="0" > <enterprise-beans> <session-deployment name="HelloBean" location="HelloBean" local-location="HelloBeanLocal" persistence-filename="HelloBean.test_default_group_1"> </session-deployment> </enterprise-beans> <assembly-descriptor> <default-method-access> <security-role-mapping name="<default-ejb-caller-role>" impliesAll="true" /> </default-method-access> </assembly-descriptor> </orion-ejb-jar>