Build the enterprise with EJB 3, JBoss Seam, and Maven 2

Enterprise resource management with JBoss Seam and Maven 2

1 2 3 4 5 6 7 Page 6
Page 6 of 7

Servlet (parent) and child project POM and file structures

The final subproject to be examined is the Web archive resource container (servlets) and its associated children. Let's first explore the overall structure, shown in Figure 6.

Seam servlets container structure
Figure 6. Seam servlets container structure (click to enlarge)

In some cases you may have multiple servlet* directories -- servlet1, servlet2, servlet3 -- with different root contexts, so that there would be one or more WAR files packaged up in the EAR file. Listing 13 shows the configuration of the parent servlets project.

Listing 13. Servlets POM file

<project>
   <modelVersion>4.0.0</modelVersion>
   <groupId>root.project</groupId>
   <artifactId>servlets</artifactId>
   <packaging>pom</packaging>
   <name>servlets</name>
   <version>1.0</version>
     <modules>
      <module>servlet</module>
   </modules>
   </project>

All potential WAR projects are declared serially in this file. No other configuration is required and certainly no Seam properties are needed. Within the single servlet child project, we find a POM file with the structure shown in Listing 14.

Listing 14. Servlet child project POM file

<project>
   <modelVersion>4.0.0</modelVersion>
   <groupId>root.project.servlets</groupId>
   <artifactId>servlet</artifactId>
   <packaging>war</packaging>
   <name>servlet</name>
   <parent>
      <groupId>root.project</groupId>
      <artifactId>servlets</artifactId>
      <version>1.0</version>
   </parent>
    <dependencies>
 <dependency>
         <groupId>commons</groupId>
         <artifactId>commons-beanutils</artifactId>
     <version>1.0</version>
 </dependency>
<dependency>
         <groupId>jboss</groupId>
         <artifactId>jboss-seam-ui</artifactId>
     <version>2.0</version>
 </dependency>
<dependency>
         <groupId>jboss</groupId>
         <artifactId>jboss-seam-debug</artifactId>
     <version>2.0</version>
 </dependency>
<dependency>
         <groupId>jsf</groupId>
         <artifactId>jsf-facelets</artifactId>
     <version>1.2MR1</version>
 </dependency>
 <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
     <version>3.8.2</version>
     <scope>test</scope>
 </dependency>
 <dependency>
         <groupId>root.project</groupId>
         <artifactId>ejbs</artifactId>
     <version>1.0</version>
     <scope>provided</scope>
 </dependency>
</dependencies>
<build>
<testSourceDirectory>src/main/test</testSourceDirectory>
</build>
</project>

Two significant aspects of this file should be noted. First, there is the compulsory parent declaration and a reference to the servlets project. (By compulsory, I mean that both the declaration of the module in the parent POM and the declaration of the parent in the servlet child's POM fuse the relationship, as far as Maven is concerned, which helps us avoid complications during the build.) Secondly, the Seam binaries (UI and Debug) can also be found from the downloaded sources lib directory.

The web-app directory contains XHTML documents (because Facelets are being used): A single page for registering a user and a confirmation page to display the information that was registered. The WEB-INF directory contains the final pieces of the Seam puzzle; its contents are shown in Figure 7.

The WEB-INF directory
Figure 7. The WEB-INF directory (click to enlarge)

The components.xml file

You can see the components.xml file in Listing 15. The entry ear-1.0/#{ejbName}/local ties the name of the EAR file as part of the context for EJB names in the JNDI namespace. This is one way of knowing which EJBs are tied to a particular enterprise artifact among many deployed on the same application server instance. The final EAR file will be named ear-1.0.ear, because there is no <finalName> configuration in the EAR project POM file.

Listing 15. components.xml

<?xml version="1.0" encoding="UTF-8"?>
<components xmlns="http://jboss.com/products/seam/components"
            xmlns:core="http://jboss.com/products/seam/core"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation=
                "http://jboss.com/products/seam/core http://jboss.com/products/seam/core-2.0.xsd
                 http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.0.xsd">

    <core:init jndi-pattern="ear-1.0/#{ejbName}/local"/>
</components>

The application's faces-config.xml file, shown in Listing 16, simply reiterates the default lifecycle phase listener, and states that the facelets view handler is the proper handler for the application's XHTML views.

Listing 16. faces-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="1.2"
              xmlns="http://java.sun.com/xml/ns/javaee"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
    <!-- Facelets support -->
    <application>
        <view-handler>com.sun.facelets.FaceletViewHandler</view-handler>
    </application>
<lifecycle>
    <phase-listener>org.jboss.seam.jsf.SeamPhaseListener</phase-listener>
</lifecycle>
</faces-config>

The only Seam-related entry in the web.xml file, shown in Listing 17, concerns the Seam listener. All other entries look pretty standard. A single empty Seam.properties file is placed in the classes directory.

Listing 17. web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.5"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <!-- Seam -->
    <listener>
        <listener-class>org.jboss.seam.servlet.SeamListener</listener-class>
    </listener>
    <context-param>
        <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
        <param-value>.xhtml</param-value>
    </context-param>
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.seam</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>10</session-timeout>
    </session-config>
</web-app>
1 2 3 4 5 6 7 Page 6
Page 6 of 7