JBoss Seam project setup with Maven — Part 2: EAR deployment
In a previous post, I discussed how to setup a Maven project for your Seam WAR application. However, most Seam developers are probably working on applications with EJB3 components to fully take advantage of the service infrastructure of the JBoss AS container. So, to complete this series, I setup a maven project for Seam EAR deployment. The project structure is as follows. The ejb module builds the JAR for EJB3 components; the war project build the web application; and the ear module builds the EAR application with necessary library JARs.
-
.
-
|-- pom.xml
-
|
-
|-- ear
-
| `-- pom.xml
-
|
-
|-- ejb
-
| |-- pom.xml
-
| |-- src
-
| `-- main
-
| |-- java
-
| | `-- com
-
| | `-- example
-
| | `-- ejb
-
| | |-- MyEnterpriseBeanImpl.java
-
| | `-- MyEnterpriseBean.java
-
| `-- resources
-
| |-- seam.properties
-
| `-- ejb-jar.xml
-
|
-
|-- war
-
|-- pom.xml
-
`-- src
-
`-- main
-
|-- java
-
| `-- com
-
| `-- example
-
| `-- SampleAction.java (and other Java source files)
-
|-- resources
-
| |-- META-INF
-
| | `-- persistence.xml
-
| |-- messages.properties
-
| `-- seam.properties
-
`-- webapp
-
|-- WEB-INF
-
| | -- components.xml
-
| | -- pages.xml
-
| | -- face-config.xml
-
| `-- web.xml
-
`-- hello.xhtml (and other web content, CSS, templates, and images)
The main pom.xml file defines the shared libraries required by all modules. It optionally uses the Seam parent POM to set the version numbers for the dependency JARs. Here is how it might look like:
-
<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">
-
-
<repositories>
-
<repository>
-
<id>jboss-snapshot</id>
-
<name>The JBoss maven repo</name>
-
<url>http://snapshots.jboss.org/maven2</url>
-
</repository>
-
</repositories>
-
<parent>
-
<groupId>org.jboss.seam</groupId>
-
<artifactId>root</artifactId>
-
<version>2.0.0-SNAPSHOT</version>
-
</parent>
-
-
<modelVersion>4.0.0</modelVersion>
-
<groupId>mystuff</groupId>
-
<artifactId>mystuff</artifactId>
-
<packaging>pom</packaging>
-
<version>1.0</version>
-
<name>mystuff</name>
-
<url>http://maven.apache.org</url>
-
-
<dependencies>
-
-
<dependency>
-
<groupId>log4j</groupId>
-
<artifactId>log4j</artifactId>
-
<scope>provided</scope>
-
</dependency>
-
-
<dependency>
-
<groupId>junit</groupId>
-
<artifactId>junit</artifactId>
-
<scope>test</scope>
-
</dependency>
-
-
</dependencies>
-
-
<modules>
-
<module>ejb</module>
-
<module>war</module>
-
<module>ear</module>
-
</modules>
-
-
<build>
-
<plugins>
-
<plugin>
-
<groupId>org.apache.maven.plugins</groupId>
-
<artifactId>maven-compiler-plugin</artifactId>
-
<configuration>
-
<source>1.5</source>
-
<target>1.5</target>
-
</configuration>
-
</plugin>
-
</plugins>
-
</build>
-
</project>
The ejb/pom.xml file defines the dependencies for the EJB3 module. Everything here is in the provided scope -- unless testing-specific libraries, which are in the test scope.
-
<project>
-
-
<parent>
-
<artifactId>mystuff</artifactId>
-
<groupId>mystuff</groupId>
-
<version>1.0</version>
-
</parent>
-
-
<modelVersion>4.0.0</modelVersion>
-
<groupId>mystuff</groupId>
-
<artifactId>ejb</artifactId>
-
<name>mystuff - ejb</name>
-
<version>1.0</version>
-
<url>http://maven.apache.org</url>
-
-
<build>
-
<finalName>ejb</finalName>
-
</build>
-
-
<dependencies>
-
-
<dependency>
-
<groupId>org.hibernate</groupId>
-
<artifactId>hibernate</artifactId>
-
<scope>provided</scope>
-
</dependency>
-
-
<dependency>
-
<groupId>org.hibernate</groupId>
-
<artifactId>hibernate-entitymanager</artifactId>
-
<scope>provided</scope>
-
</dependency>
-
-
<dependency>
-
<groupId>org.hibernate</groupId>
-
<artifactId>hibernate-annotations</artifactId>
-
<scope>provided</scope>
-
</dependency>
-
-
<dependency>
-
<groupId>org.hibernate</groupId>
-
<artifactId>hibernate-validator</artifactId>
-
<scope>provided</scope>
-
</dependency>
-
-
<dependency>
-
<groupId>org.jboss.seam</groupId>
-
<artifactId>jboss-seam</artifactId>
-
<scope>provided</scope>
-
</dependency>
-
-
<dependency>
-
<groupId>javax.ejb</groupId>
-
<artifactId>ejb-api</artifactId>
-
<scope>provided</scope>
-
</dependency>
-
-
<dependency>
-
<groupId>hsqldb</groupId>
-
<artifactId>hsqldb</artifactId>
-
<version>1.7.2</version>
-
<scope>test</scope>
-
</dependency>
-
-
</dependencies>
-
-
</project>
The war/pom.xml file defines the dependencies for the WAR module. It depends on the ejb module.
-
<?xml version="1.0" encoding="UTF-8"?>
-
<project>
-
<parent>
-
<artifactId>mystuff</artifactId>
-
<groupId>mystuff</groupId>
-
<version>1.0</version>
-
</parent>
-
<modelVersion>4.0.0</modelVersion>
-
-
<groupId>mystuff</groupId>
-
<artifactId>war</artifactId>
-
<name>mystuff - web</name>
-
<version>1.0</version>
-
<packaging>war</packaging>
-
<url>http://maven.apache.org</url>
-
-
<build>
-
<finalName>war</finalName>
-
</build>
-
-
<dependencies>
-
-
<dependency>
-
<groupId>mystuff</groupId>
-
<artifactId>ejb</artifactId>
-
<version>1.0</version>
-
<scope>provided</scope>
-
<type>ejb</type>
-
</dependency>
-
-
<!-- The following 4 dependencies are included in the WEB-INF/lib of the war -->
-
-
<dependency>
-
<groupId>org.jboss.seam</groupId>
-
<artifactId>jboss-seam-ui</artifactId>
-
</dependency>
-
-
<dependency>
-
<groupId>org.jboss.seam</groupId>
-
<artifactId>jboss-seam-debug</artifactId>
-
</dependency>
-
-
<dependency>
-
<groupId>com.sun.facelets</groupId>
-
<artifactId>jsf-facelets</artifactId>
-
</dependency>
-
-
<dependency>
-
<groupId>org.richfaces.ui</groupId>
-
<artifactId>richfaces-ui</artifactId>
-
</dependency>
-
-
<!-- The "provided" dependencies are only need for compilation -->
-
-
<dependency>
-
<groupId>javax.servlet</groupId>
-
<artifactId>servlet-api</artifactId>
-
<scope>provided</scope>
-
</dependency>
-
-
<dependency>
-
<groupId>org.jboss.seam</groupId>
-
<artifactId>jboss-seam</artifactId>
-
<scope>provided</scope>
-
</dependency>
-
-
<dependency>
-
<groupId>javax.faces</groupId>
-
<artifactId>jsf-api</artifactId>
-
<scope>provided</scope>
-
</dependency>
-
-
<dependency>
-
<groupId>javax.faces</groupId>
-
<artifactId>jsf-impl</artifactId>
-
<scope>provided</scope>
-
</dependency>
-
-
<dependency>
-
<groupId>org.hibernate</groupId>
-
<artifactId>hibernate-validator</artifactId>
-
<scope>provided</scope>
-
</dependency>
-
-
</dependencies>
-
</project>
The ear/pom.xml file defines how the EAR application is assembled. You need to declare any JARs you want to include in the EAR as dependencies. I also used a JBoss-specific element to setup the class loader repository for the application. It is often needed in JPA applications. Yes, it is verbose -- if you have a better idea, let me know.
-
<project>
-
-
<parent>
-
<artifactId>mystuff</artifactId>
-
<groupId>mystuff</groupId>
-
<version>1.0</version>
-
</parent>
-
-
<modelVersion>4.0.0</modelVersion>
-
<groupId>mystuff</groupId>
-
<artifactId>ear</artifactId>
-
<name>mystuff - ear</name>
-
<packaging>ear</packaging>
-
<version>1.0</version>
-
<url>http://maven.apache.org</url>
-
-
<dependencies>
-
-
<dependency>
-
<groupId>mystuff</groupId>
-
<artifactId>ejb</artifactId>
-
<version>1.0</version>
-
<type>ejb</type>
-
</dependency>
-
-
<dependency>
-
<groupId>mystuff</groupId>
-
<artifactId>war</artifactId>
-
<version>1.0</version>
-
<type>war</type>
-
</dependency>
-
-
<dependency>
-
<groupId>org.jboss.seam</groupId>
-
<artifactId>jboss-seam</artifactId>
-
<type>ejb</type>
-
</dependency>
-
-
<dependency>
-
<groupId>org.jboss.seam</groupId>
-
<artifactId>jboss-el</artifactId>
-
<exclusions>
-
<exclusion>
-
<groupId>javax.el</groupId>
-
<artifactId>el-api</artifactId>
-
</exclusion>
-
</exclusions>
-
<type>jar</type>
-
</dependency>
-
-
<dependency>
-
<groupId>commons-beanutils</groupId>
-
<artifactId>commons-beanutils</artifactId>
-
<exclusions>
-
<exclusion>
-
<groupId>commons-logging</groupId>
-
<artifactId>commons-logging</artifactId>
-
</exclusion>
-
</exclusions>
-
<type>jar</type>
-
</dependency>
-
-
</dependencies>
-
-
<build>
-
<plugins>
-
<plugin>
-
<groupId>org.apache.maven.plugins</groupId>
-
<artifactId>maven-ear-plugin</artifactId>
-
<configuration>
-
<jboss>
-
<version>4</version>
-
<loader-repository>mystuff:loader=mystuff.ear</loader-repository>
-
</jboss>
-
-
<modules>
-
<webModule>
-
<groupId>mystuff</groupId>
-
<artifactId>war</artifactId>
-
<contextRoot>mystuff</contextRoot>
-
</webModule>
-
-
<ejbModule>
-
<groupId>mystuff</groupId>
-
<artifactId>ejb</artifactId>
-
</ejbModule>
-
-
<ejbModule>
-
<groupId>org.jboss.seam</groupId>
-
<artifactId>jboss-seam</artifactId>
-
</ejbModule>
-
-
<!-- The stuff that needs to go in the lib directory.
-
They will not be included in application.xml -->
-
-
<jarModule>
-
<groupId>org.jboss.seam</groupId>
-
<artifactId>jboss-el</artifactId>
-
<bundleDir>lib</bundleDir>
-
</jarModule>
-
-
<jarModule>
-
<groupId>commons-beanutils</groupId>
-
<artifactId>commons-beanutils</artifactId>
-
<bundleDir>lib</bundleDir>
-
</jarModule>
-
-
</modules>
-
</configuration>
-
</plugin>
-
</plugins>
-
</build>
-
-
</project>
October 9th, 2007 at 3:30 pm
nice post! you just need to remove the ‘ejb type’ of ‘jboss-seam’ dependency in the ‘ear/pom.xml’ file…
org.jboss.seam
jboss-seam
October 9th, 2007 at 11:07 pm
Gerson,
I think that the jboss-seam.jar does need to be listed as an EJB module in order for the EJB transaction listeners, EJb Timers, and other features to function. Am I missing something here?
cheers
Michael
October 10th, 2007 at 8:42 am
It would be really nice to see a maven2 example with embedded jboss running some ejb3 tests. Something similar in functionality, but just focused on seam, as appfuse. Creating a simple site for users and groups coming from the database.
I’ve been attempting to setup embedded jboss and its a hurdle to get to the point where you can do some testing.
October 10th, 2007 at 8:45 am
hi Michael,
I’ve just checked the deployment descriptor of Seam 2.x and noticed that the jboss-seam.jar is REALLY an EJB module (Seam 1.x do NOT list as an EJB module). But in this case, once the ‘Seam root pom’ just declares the jboss-seam.jar as an JAR type, its version must be specified for EJB type in the ejb/pom.xml… if not, the maven will complain about ‘version missing’. I’m not a maven expert but maybe it would be helpful if the ‘Seam root pom’ could also declare the jboss-seam’s EJB type version so that it would not be necessary to “hardcode” the version in application’s pom.
October 10th, 2007 at 9:00 am
uops, I mean… I’ve just checked the deployment descriptor files of the applications that use Seam 2.x and Seam 1.x…
Sorry.
October 10th, 2007 at 9:17 am
Hi Michael,
could you please elaborate on why the jboss-seam.jar needs to be included like this or some features won’t work?
TIA,
Tobias
October 10th, 2007 at 2:11 pm
Gerson,
I guess it is a tricky situation for the Seam root pom — it has to accommodate WAR-only deployment as well. I am not sure … But you do need to use jboss-seam.jar as an EJB module to take full advantage of EJB3 features in Seam.
cheers
Michael
October 10th, 2007 at 2:14 pm
Tobias,
If you look at the classes inside jboss-seam.jar, there are quite a few EJB3 components. The ones I am aware of are the EJB3 transaction listener and the EJB3 Timer for asynchronous methods.
You might not need them — you can use jboss-seam.jar in a WAR deployment after all. So, do not worry if you do not encounter any issues.
cheers
Michael
October 10th, 2007 at 6:42 pm
I think “mystuff” and “myapp” groups and artifacts are a bit messed up between parent and children POMs.
October 10th, 2007 at 7:21 pm
Yuriy,
Good catch! I fixed it now.
cheers
Michael
October 11th, 2007 at 2:30 pm
Ok, another try…
Perhaps this may help someone:
TestNg integration for Seam 1.2.1(seam-booking example):
1. this link helped me
http://docs.codehaus.org/display/MAVENUSER/How+to+use+the+JBoss+Embedded+EJB3+Container+for+Unit+testing
2. put generated pom.xmls and jars into a local or your remote maven repository
3. use generated “microcontainer” jars as dependencies of the ejb-module
4. other used dependencies (jsf-api (1.2), testng (5.5), servlet-api(2.5), dbunit(2.1))
5. ejb-module pom:
- use the maven-surefire-plugin (2.4-collab-SNAPSHOT)
- configure a plugin repository: http://people.apache.org/repo/m2-snapshot-repository/
6. put test-classes in ejb-module/src/test/java
7. now we need some other files in ejb-module/src/test/resources :
from the frontend:
- components.xml into ejb-module/src/test/resources/WEB-INF/
- components.properties (embeddedEjb = false, jndiName = ejbName/local) into ejb-module/src/test/resources/
all from seam-1.2.1.GA/embedded-ejb/conf into ejb-module/src/test/resources/
If you have an other or better solution…
Please give it to me…
It took much time to get the right dependencies and let them work together…
I think we need a online maven repository for seam and the most used third party jars.
October 11th, 2007 at 2:41 pm
i have to correct me :
this is my components.xml in the folder: ejb-module/src/test/resources
embeddedEjb true
jndiPattern \#{ejbName}/local
October 11th, 2007 at 3:38 pm
an other thing is the hot deployment (eclipse + m2eclipse-plugin http://m2eclipse.codehaus.org/)
my solution (also not really satisfying):
- in the jboss-service.xml configure a new deploy folder:
….eclipseWorkspace/myProject/ear/target/deploy/
- ear/pom.xml :
place in the configuration of the ear-plugin
${project.build.directory}/deploy/${project.build.finalName}.ear
also in the configuration node give our “webModule”:
true
- war/pom.xml
place in the configuration of the war-plugin
${project.parent.basedir}/ear/target/deploy/projectName-${pom.version}.ear/${project.build.finalName}.war
in eclipse right-click the project,
-> properties -> builders -> new -> maven build:
base directory:
${workspace_loc:/trilobita/trilobita-frontend/}
and
Auto Build Goals: compile war:exploded
the problem is, that every change in the whole project leads to an auto build…
so i turn it off while not working on war-files
October 11th, 2007 at 3:44 pm
an other thing is the hot deployment (eclipse + m2eclipse-plugin http://m2eclipse.codehaus.org/)
my solution (also not really satisfying):
- in the jboss-service.xml configure a new deploy folder:
…eclipseWorkspace/myProject/ear/target/deploy/
- ear/pom.xml :
place a “workDirectory”-node in the configuration of the ear-plugin containing:
${project.build.directory}/deploy/${project.build.finalName}.ear
also in this configuration node give our “webModule”:
a node “unpack” containing
true- war/pom.xml
place in the configuration of the war-plugin
a node “webappDirectory” containing
${project.parent.basedir}/ear/target/deploy/projectName-${pom.version}.ear/${project.build.finalName}.war
in eclipse right-click the project,
-> properties -> builders -> new -> maven build:
base directory:
${workspace_loc:/trilobita/trilobita-frontend/}
and
Auto Build Goals: compile war:exploded
the problem is, that every change in the whole project leads to an auto build…
so i turn it off while not working on war-files
October 11th, 2007 at 4:22 pm
okay reading other posts i found the maven repository for seam. good job !
i will try it.
October 18th, 2007 at 9:42 am
Anyone have issues with provided scope in the WAR file for your EJB? I’m deploying to JBoss 4.2 and the WAR file doesn’t seem to know about the EJB contained in the EAR. Is this normal?
October 18th, 2007 at 10:18 am
Ok, nevermind. I figured it out.
JBoss has different class loading mechanism then other EE containers. You have to specify a loader repository in jboss-app and jboss-web.xml files.
October 24th, 2007 at 1:54 am
Great article!
But if I follow these instructions and compare my result to what seam-gen generates, I am missing files in the ear’s lib directory. Specifically:
antlr-runtime.jar
backport-util-concurrent.jar
commons-digester.jar
commons-fileupload.jar
drools-compiler.jar
drools-core.jar
icefaces-comps.jar
icefaces-facelets.jar
icefaces.jar
jbpm-jpdl.jar
mvel14.jar
I suspect that some additional modules need to be specified for the ear’s pom.xml.
October 24th, 2007 at 2:03 am
Also, I had to add a dependency to the ear’s pom.xml to avoid the el-api-1.0.jar from being included in the ear’s lib:
javax.el
el-api
1.0
provided
October 24th, 2007 at 9:54 am
Logan,
Seam integrates with a lot of other frameworks. The jars you listed are needed when you need your Seam app to utilize jBPM, Drools (for advanced security), and icefaces.
But for simple web apps, those jars are not needed.
cheers
Michael
October 31st, 2007 at 12:54 am
> Yes, it is verbose — if you have a better idea, let me know.
Well, what about not declaring the ejbModule entries in a first place. They are totally useless unless you want to configure the way the EJBs are bundled in the ear (just like the lib directory in the javaModule in the same example).
You can also use dependencyManagement in the parent pom to share the version of the libs of you’re using, even if they are from the same project. This restricts the dependencies to the groupId/artifactId.
Hope that helps.
November 2nd, 2007 at 5:33 am
Micheal,
A great contribution to what is a very frustrating area of development. Speaking of which when I try and use mvn install -N on the root pom maven kindly informs me that I am missing ‘dependencies.dependency.version’ - placing a version into the junit entry fixes this problem but is this intended on your part? Or is Maven broken (again)? It does make it very difficult to convince managers of the benefits of using Maven but I do think this contribution goes some way to achieving this.
Thanks
November 7th, 2007 at 1:02 am
Hello all,
could somebody publish example as a zip file, please. I tried create my own along Michaels instructions, but finally I am not able deploy ear file to jboss 4.2.2.GA. I am getting a lots of ClassNotFound exceptions.
Thanks
Dusan
November 8th, 2007 at 7:48 pm
A nice stuff to do is put maven to filter the WEB-INF :
…
maven-war-plugin
src/resources-WEB-INF
WEB-INF
true
…
for example
This way you can filter the componet.xml
So you culd filter some propertys like (In my case):
jndi-pattern=”evento-ear-${project.version}/#{ejbName}/local”
and some configurable component property, according some active profile:
…
${diretorioUploadRetornoBB}
…
for example
January 14th, 2008 at 10:58 am
You have to put this project up for download somehwere!
March 27th, 2008 at 11:10 am
Can you please update a sample application with this configuration…
I am working on this for 2 weeks with no success.I made lots of changes for lots of deployment exceptions,but I cannot solve the last one:”java.lang.IllegalStateException: Application was not properly initialized at startup, could not find Factory: javax.faces.context.FacesContextFactory”…
thanks…
July 3rd, 2008 at 5:56 am
Hi, can anyone explain how to setup eclipse’s EJB project so that it would be on one hand a maven project, on the other hand a valid eclipse EJB module. The problem is that I can’t make hot deployment work. There is a post by Meiko Rachimow about that above. Can anyone give a more detailed explanation, please. Thank you…
September 16th, 2008 at 2:46 pm
Has anyone got this to work? I get java.lang.ClassNotFoundException: org.jboss.seam.servlet.SeamListener after components are validated.
Anyone that has a zip for this startup project with all the things in place?
November 30th, 2008 at 5:24 pm
— It optionally uses the Seam parent POM to set the version numbers for the dependency JARs. —
First of all thanks for this tutorial but I have some problems. I just started to build some apps with maven and seam. It keeps complaining about the version of jboss and jboss-el. I have set the parent in my main pom to the jboss seam 2.1.1-snapshot but he gives me errors about the version.
I did exactly copied the dependencies from above examples but I can’t figure it out.
Maven should get the version automaticly from the parent pom in my main pom right?
regards,
Derk
January 17th, 2009 at 10:45 pm
May you attach a zip file for this tutorial, maybe we can work from there. Thanx
January 22nd, 2009 at 9:12 am
Which version of Maven are you guys who had success using? I suspect that I have an issue with mvn 2.0.9 not inheriting dependencies and versions from the seam root pom.
March 18th, 2009 at 8:09 am
Hi, michael. I’m have some questiom about maven2 with seam ejb project. My project is structured like this:
-> src
-> pageflows
-> web
-> dist
-> EarContent
-> resources
-> ejbModule
-> build
-> sql
It was created by the eclipse plugin with the JBoss tools.
I wonder if I should continue using this structure and only create the pom’s. Or do I customize the structure of the project to then create the pom’s.
Because the structure of the project that used this example as different from mine. And I would like some tips for setting up of my pom on your point of view.
March 19th, 2009 at 8:09 am
Michael, please attach the source code of this example.