JBoss Seam project setup with Maven — Part 1: WAR deployment

Pete Muir recently posted that Seam 2.0 will support Maven integration. It is perfect timing for me since I have just started to use Maven in my new projects. So, I went through the exercise to setup simple Seam web projects in Maven. It is really quite easy. The project builds a single WAR for deployment (you can only use Seam POJO in the WAR -- no EJBs). You can configure it to generate WAR for JBoss AS or Tomcat 6. The beauty of using Maven is that you do not need to worry about things like finding the right version of JARs, setting up the project structure, managing build script etc. In fact, there is no build script to write. So, here is the structure of the source project.

CODE:
  1. .
  2.  |-- pom.xml
  3.  `-- src
  4.      `-- main
  5.          |-- java
  6.          |   `-- com
  7.          |       `-- example
  8.          |             `-- SampleAction.java (and other Java source files)
  9.          |-- resources
  10.          |   |-- META-INF
  11.          |   |   `-- persistence.xml
  12.          |   `-- seam.properties
  13.          `-- webapp
  14.              |-- WEB-INF
  15.              |    | -- components.xml
  16.              |    | -- pages.xml
  17.              |    | -- face-config.xml
  18.              |     `-- web.xml
  19.              `-- hello.xhtml (and other web content, CSS, templates, and images)

As you can see, you put your application code and configuration in the following directories.

  • All the Java source code (e.g., entity beans, Seam POJOs) go into src/main/java.
  • All Seam and web-related configuration files go into src/main/webapp/WEB-INF.
  • The JPA configuration goes into resources/META-INF/persistence.xml.
  • All web content goes into src/main/webapp.
  • The resources/seam.properties file is an empty file. It is require for Seam to scan annotations in this WAR

The dependency JARs are declared in the pom.xml file. Below is the pom.xml I used to generate a WAR for JBoss AS deployment. A couple of things to notice here:

  • I set the Seam official POM as my "parent" so that I can let Seam figure out the correct versions of the dependency JARs. Notice that I do not need to specify the Facelets JAR version in my POM. Seam will choose a compatible version for me.
  • The compiler setting must be "1.5" so that it can handle annotations.
  • The javax.el.el-api jar needs to be in the provided scope as it conflicts with the one already in JBoss and Tomcat 6.

That's it. Here is the pom.xml.

XML:
  1. <project xmlns="http://maven.apache.org/POM/4.0.0"
  2.          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3.          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  4.  
  5.   <repositories>
  6.     <repository>
  7.       <id>jboss-snapshot</id>
  8.       <name>The JBoss maven repo</name>
  9.       <url>http://snapshots.jboss.org/maven2</url>
  10.     </repository>
  11.   </repositories>
  12.  
  13.   <parent>
  14.     <groupId>org.jboss.seam</groupId>
  15.     <artifactId>root</artifactId>
  16.     <version>2.0.0-SNAPSHOT</version>
  17.   </parent>
  18.  
  19.   <modelVersion>4.0.0</modelVersion>
  20.  
  21.   <groupId>mytest</groupId>
  22.   <artifactId>seam-maven</artifactId>
  23.   <name>helloworld</name>
  24.   <version>1.0</version>
  25.   <packaging>war</packaging>
  26.   <url>http://maven.apache.org</url>
  27.  
  28.   <build>
  29.     <finalName>helloworld</finalName>
  30.     <plugins>
  31.       <plugin>
  32.         <groupId>org.apache.maven.plugins</groupId>
  33.         <artifactId>maven-compiler-plugin</artifactId>
  34.         <configuration>
  35.           <source>1.5</source>
  36.           <target>1.5</target>
  37.         </configuration>
  38.       </plugin>
  39.     </plugins>
  40.   </build>
  41.  
  42.   <dependencies>
  43.  
  44.     <dependency>
  45.       <groupId>org.jboss.seam</groupId>
  46.       <artifactId>jboss-seam</artifactId>
  47.     </dependency>
  48.  
  49.     <dependency>
  50.       <groupId>org.jboss.seam</groupId>
  51.       <artifactId>jboss-el</artifactId>
  52.       <exclusions>
  53.         <exclusion>
  54.           <groupId>javax.el</groupId>
  55.           <artifactId>el-api</artifactId>
  56.         </exclusion>
  57.       </exclusions>
  58.     </dependency>
  59.  
  60.     <dependency>
  61.       <groupId>org.jboss.seam</groupId>
  62.       <artifactId>jboss-seam-ui</artifactId>
  63.     </dependency>
  64.  
  65.     <dependency>
  66.       <groupId>com.sun.facelets</groupId>
  67.       <artifactId>jsf-facelets</artifactId>
  68.     </dependency>
  69.  
  70.   </dependencies>
  71.  
  72. </project>

Now, what if I want the WAR to be deployed in plain Tomcat 6? No problem, just add the JSF and Hibernate dependencies as follows. There is no need to meddle with commons jars and other 3rd party JARs since JSF and Hibernate dependencies automatically resolve them! Of course, plain Tomcat 6 does not provide a JTA transaction manager, so you will need to provide your own or use RESOURCE_LOCAL transaction -- but you should already knew that if you choose Tomcat ...

XML:
  1. <!-- The following dependencies are needed for Tomcat 6 deployment -->
  2.  
  3.     <dependency>
  4.       <groupId>javax.faces</groupId>
  5.       <artifactId>jsf-api</artifactId>
  6.     </dependency>
  7.  
  8.     <dependency>
  9.       <groupId>javax.faces</groupId>
  10.       <artifactId>jsf-impl</artifactId>
  11.     </dependency>
  12.  
  13.     <dependency>
  14.       <groupId>org.hibernate</groupId>
  15.       <artifactId>hibernate</artifactId>
  16.     </dependency>
  17.  
  18.     <dependency>
  19.       <groupId>org.hibernate</groupId>
  20.       <artifactId>hibernate-validator</artifactId>
  21.     </dependency>
  22.  
  23.     <dependency>
  24.       <groupId>org.hibernate</groupId>
  25.       <artifactId>hibernate-annotation</artifactId>
  26.     </dependency>
  27.  
  28.     <dependency>
  29.       <groupId>org.hibernate</groupId>
  30.       <artifactId>hibernate-entitymanager</artifactId>
  31.     </dependency>

So, go and have fun with Maven now! Let me know if there is any issues!

21 Responses to “JBoss Seam project setup with Maven — Part 1: WAR deployment”

  1. JBoss Seam project setup with Maven « outaTiME Says:

    [...] October 2nd, 2007 Pete Muir recently posted that Seam 2.0 will support Maven integration. It is perfect timing for me since I have just started to use Maven in my new projects. So, I went through the exercise to setup simple Seam web projects in Maven. It is really quite easy. The project builds a single WAR for […] [...]

  2. Ivan Memruk Says:

    I have set up seam 1.2.1 with maven 2 (and split a project into a couple of maven artifacts, e.g. model, services, ear and stuff).
    Took a lot of pain but the result was a very convenient build framework.
    Nice to know you guys paid attention to this and there will be no need to do it manually any more.

  3. Siarhei Says:

    This is excellent news!

  4. Jakob Says:

    How do you use Maven with EJBs? Shouldn’t there be a /src/webapp/java and /src/ejb/java folders? And couldn’t we have EJBs in the war if we were using embeddable JBoss with Tomcat?

  5. Michael Yuan Says:

    Jakob,

    Good question. I’d prefer to deploy EJB3 beans in a EAR in JBoss AS rather than meddling with Tomcat + JBoss Embedded.

    I will write up new entry outlining an EAR project structure next. Stay tuned.

    cheers
    Michael

  6. Ivan Memruk Says:

    Jakob: in short, you need a special deployment type in maven (ejb3 instead of jar), but it also needs some further tweaks. You can figure out from the maven docs. At least that’s what I did for seam 1.

  7. Michael Maraist Says:

    I’m not sure how you get an ear, ejb-jar and war to work in one directory space in maven.. But generally what you do is create 4 directories

    myproj/
    pom.xml (packaging pom)
    myproj-api/
    pom.xml (packaging jar)
    myproj-ejb/
    pom.xml (packaging ejb/jar)
    myproj-war/
    pom.xml (packaging war)
    myproj-ear/
    pom.xml (packaging ear)

    The -api is obviously optional, but useful with EJBs and SOAP services.

  8. sakuraba Says:

    Does this mean I could go “mvn jetty:run” on that thing too? I have heard that some users are using jetty to develop and JBoss in production, which seems like a great choice to me.

    Besides Best-Practices the mavenized Seam HAS to be in the new edition of your Seam Book! ;)

    Are there any Seam archetypes yet?

  9. Michael Yuan Says:

    sakuraba:

    We do not yet have an archetype for Seam, and nor do we have a deployment plugin yet … But as you see, Seam/Maven integration is still in very early stage. I am sure that we will have all those with the help from the community! :)

    Yes, we will have a chapter on Maven setup in the new edition of the book!

    cheers
    Michael

  10. sakuraba Says:

    Thank you Michael!

    I have read your book and I must say that you are very talented in explaining complex stuff. It is a very good read and I cannot wait for the next edition.

  11. Yuriy Zubarev Says:

    Hello,

    I’m trying to set up Seam (2.0.0) Web App under Tomcat 6.0 in a such a way as to have 2 POM project. One is with entities (@Entity) and another one is a web app itself (and there is a parent POM of course). The idea is that entities could be re-used between different sub-projects.

    He is my structure:


    .
    |-- pom.xml
    |
    |-- entity
    | |-- pom.xml
    | |-- src
    | |-- main
    | |-- java
    | | |-- entitypackage
    | | |-- Book.java
    | |-- resources
    | |-- seam.properties
    |-- webapp
    |-- pom.xml
    |-- src
    |-- main
    |-- java
    | |-- webpackage
    | |-- BookController.java
    |-- resources
    | |-- seam.properties
    |-- webapp
    |-- META-INF
    | |-- context.xml
    | |-- persistence.xml
    |-- WEB-INF
    |-- web.xml
    |-- components.xml
    |-- pages.xml

    In BookController I have something like this:


    this.books = em.createQuery("select b from entitypackage.Book b").getResultList();

    When the web app is running this is what I see in a log file:


    WARNING: no persistent classes found for query class: select b from entitypackage.Book b

    When I move Book.java to webapp project, everything works like a charm. I also tried to provide persistence.xml under entity/META-INF and provide “class” element in there but it didn’t help.

    I was wondering how I can separate entity (and java beans/session) classes from the actual web application and still enjoy the benefits of Seam. Just to stress it again, I’m building a light-weight web app to be run under Tomcat without EJB embedded container.

    Thank you.
    Yuriy

  12. Michael Yuan Says:

    Yuriy,

    You might want to try explicitly specify the entity classes in the <class> elements in your persistence.xml …

    cheers
    Michael

  13. Yuriy Zubarev Says:

    Thank you Michael. I tried it to no avail. I also posted this question to Seam forum.

  14. Wesley Hales Says:

    Deploying Seam on Tomcat with EJB3

  15. Meraj Says:

    Hi,
    I am usin @Name(”user”) annotation on my entity class. What dependencies i need to define in my pom

  16. Meraj Says:

    Hi,
    I am using custom listener class calles vsapageloadlistener. i have defined this in faces_config.xml. is it mandatory to use
    “org.jboss.seam.jsf.SeamPhaseListener”

  17. Gordon DuQuesnay Says:

    I am trying to convert the ‘JPA’ example that ships with Seam 2.0 GA to maven by following this. I think I have everything setup as directed but when I compare the wars generated the maven generated war is different e.g. my META-INF end up under WEB-INF\classes and different one with a manifest and some maven stuff ends up in the root.

  18. Manuel Palacio Says:

    The correct groupId for jboss el is:

    org.jboss.el

    and not

    org.jboss.seam

    Make sure you refer to the latest parent pom

  19. Geoff M. Says:

    Great article + I got a lot out of your JBoss Seam Simplicity and Power Beyond Java EE Book!

    Quick question. I’m using the JBoss Tools plugin for Eclipse and it works great but it appears to expect the folders to be in a different place than maven. For example the plugin creates a WebContent directory and maven expects the folder to be src/main/webapp.

    What is the best practice for using both maven and Eclipse with JBoss Tools plugin simultaneously? Should I try to get Maven to use the plugin’s style of folders or is it possible to specify the settings for the plugin?
    Thanks!

  20. Michael Yuan Says:

    Sorry Geoff. I am more of a NetBeans guy … I think Seam or JBoss Tools forum would be better places to ask this question. :)

  21. Ha Ta Says:

    I convert successfully the ‘JPA’ example in Seam 2.1.1.GA to maven by following this. But I can not run the unit test, could you please give me more details configuration information to run unit test in maven?

    Thanks very much

Leave a Reply