Friday, January 28, 2011

Use Maven to Build ear

The following is an example of using Maven to build a Java ear application. The ear has one web module, one ejb module, and one jar module.

The top level directory

The top directory layout is as follows:
xyz
    xyz-common
    xyz-ear
    xyz-ejb
    xyz-web
    pom.xml

The file pom.xml is the following:
<?xml version="1.0" encoding="UTF-8"?>
    <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/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
    
      <groupId>com.foo.xyz</groupId>
      <artifactId>xyz</artifactId>
      <version>1.0</version>
      <packaging>pom</packaging>
    
      <name>xyzmaven</name>
 
      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <env>dev</env>
      </properties> 

        <profiles>      
          <profile>
           <id>dev</id>
           <properties>
            <env>dev</env>
           </properties>
          </profile>
          <profile>
           <id>prd</id>
           <properties>
            <env>prd</env>
           </properties>
          </profile>
     </profiles>
      
      <modules>
        <module>xyz-common</module>
        <module>xyz-web</module>
        <module>xyz-ejb</module>
        <module>xyz-ear</module>
      </modules>
</project>

In this top directory, run "mvn clean install" will build and install all the modules. One can also go to each individual module to run "mvn clean install".

xyz-common

This is a jar module that contains common classes used by other modules.
Its content layout:
src
  main
     java
  test
     java
pom.xml

The file pom.xml is as follows.
<?xml version="1.0" encoding="UTF-8"?>
   <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
     <modelVersion>4.0.0</modelVersion>
     <parent>
       <artifactId>xyz</artifactId>
       <groupId>com.foo.xyz</groupId>
       <version>1.0</version>
     </parent>
     <artifactId>xyz-common</artifactId>
     <packaging>jar</packaging>
     <version>1.0</version>
     <name>xyz-common</name>
     <build>
     <plugins>
     
        <plugin>
         <inherited>true</inherited>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-compiler-plugin</artifactId>
         <configuration>
          <source>1.6</source>
          <target>1.6</target>
         </configuration>
        </plugin>
        
        <plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-surefire-plugin</artifactId>
       <configuration>
               <skipTests>true</skipTests>
        <testFailureIgnore>true</testFailureIgnore>
       </configuration>
      </plugin>
      
        <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-jar-plugin</artifactId>
         <version>2.3.1</version>
         <executions>
            <execution>
                <goals>
                  <goal>test-jar</goal>    
                </goals>
            </execution>
       </executions>
        </plugin>
     
       </plugins>
     
      </build>
      <dependencies>
       <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring</artifactId>
        <version>2.5.5</version>
       </dependency>
     
     </dependencies>
     
   </project>
   

Notes:
  1. The test files are skipped.
  2. The goal "test-jar" will generate xyz-common-1.0-tests.jar

xyz-ejb

This is the ejb module. The file structure is the following.
src
    main
        java
        resources
            META-INF
               ejb-jar.xml
               weblogic-ejb-jar.xml
pom.xml


The file pom.xml is as the following:
<?xml version="1.0" encoding="UTF-8"?>
    <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <modelVersion>4.0.0</modelVersion>
      <parent>
        <artifactId>xyz</artifactId>
        <groupId>com.foo.xyz</groupId>
        <version>1.0</version>
      </parent>
      <artifactId>xyz-ejb</artifactId>
      <version>1.0</version>
      <packaging>jar</packaging>
      <name>xyz-ejb Maven Webapp</name>
      <build>
        <!-- <finalName>xyz-ejb</finalName> -->
        <plugins> 
             <plugin>
         <inherited>true</inherited>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-compiler-plugin</artifactId>
         <configuration>
          <source>1.6</source>
          <target>1.6</target>
         </configuration>
             </plugin>
           
           
             <plugin>
         <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-ejb-plugin</artifactId> 
      <version>2.3</version> 
      <configuration>
         <ejbVersion>2.1</ejbVersion>
      </configuration>
             </plugin>
          </plugins>
        
      </build>
      <dependencies>
         <dependency>
           <groupId>com.foo.xyz</groupId>
           <artifactId>xyz-common</artifactId>
           <version>1.0</version>
        </dependency>
        
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>3.8.1</version>
          <scope>test</scope>
        </dependency>
      </dependencies>
    </project>
Notes:
  1. Just run "mvn clean package" will create the xyz-ejb-1.0.jar. It seems that you do not
    need to run "mvn ejb:ejb".
  2. In this example, the ejb version used is the old 2.1 version.

After xyz-ejb-1.0.jar is built successfully, its file layout is as follows:
com
META-INF
   ejb-jar.xml
   weblogic-ejb-jar.xml


xyz-web

This is the web module. The file structure as follows.
src
              main
                     filters
                            filter-dev.properties
                            filter-prd.properties
                     java
                     resources
                            views.properties
                            messages.properties
                     webapp
                            some_jsp_folder
                            WEB-INF
                                   flows
                                   jsp
                                   other_folders
                                   tld
                                   faces-config.xml
                                   web.xml
                                   weblogic.xml
                                   xyz-servlet.xml

       pom.xml


The file pom.xml is as follows.
<?xml version="1.0" encoding="UTF-8"?>
    <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <modelVersion>4.0.0</modelVersion>
      <parent>
        <artifactId>xyz</artifactId>
        <groupId>com.foo.xyz</groupId>
        <version>1.0</version>
      </parent>
      <artifactId>xyz-web</artifactId>
      <version>1.0</version>
      <packaging>war</packaging>
      <name>xyz-web Maven Webapp</name>   
      
      <build>
        <!-- <finalName>xyz</finalName> -->
        <filters>
       <filter>${basedir}/src/main/filters/filter-${env}.properties</filter>
      </filters>
        <resources>
         <resource>
          <directory>${basedir}/src/main/resources</directory>
          <filtering>true</filtering>
         </resource>
    
        
        </resources>
        <plugins>
         <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <configuration>
           <source>1.6</source>
           <target>1.6</target>
          </configuration>
         </plugin>
      
         <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-surefire-plugin</artifactId>
          <configuration>
           <testFailureIgnore>true</testFailureIgnore>
          </configuration>
         </plugin>
      
        
       <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.0.2</version>
        <configuration>
                <webResources>
              <resource>
         <directory>${basedir}/src/main/webapp/WEB-INF</directory>
         <filtering>true</filtering>
         <targetPath>WEB-INF</targetPath>
           <includes>
             <include>xyz-servlet.xml</include>
             <include>web.xml</include>
             <include>jsp/css/xp.css</include>
             <include>jsp/shared/header_jsf.jsp</include>
             <include>jsp/shared/mainTemplate.xhtml</include>
           </includes>
              </resource>
              
              <resource>
               <directory>${basedir}/src/main/webapp</directory>
               <filtering>true</filtering>
               <includes>
                   <include>fooDir/foo.xhtml</include>
                   <include>css/xp.css</include>
               </includes>
              </resource>
              
           </webResources>
         </configuration>
       </plugin>
      
        </plugins>
     </build>
     
      <dependencies>
                    <dependency>
             <groupId>icefaces.icefaces-facelets</groupId>
             <artifactId>icefaces-facelets</artifactId>
             <version>1.6.2</version>
            </dependency>
            <dependency>
             <groupId>icefaces.icefaces-comps</groupId>
             <artifactId>icefaces-comps</artifactId>
             <version>1.6.2</version>
        </dependency>
      </dependencies>
    </project>
    

Notes:
  1. One important thing is how to filter files. Here maven-war-plugin is used.

After xyz-web-1.0.jar is built successfully, its file layout is as follows:
some_jsp_folder
      WEB-INF
            classes
                  messages.properties
                  views.properties
            flows
            jsp
            other_folders
            tld
            lib
                  icefaces-facelets-1.6.2
                  icefaces-comps-1.6.2.jar
            web.xml
            xyz-servlet.xml
            weblogic.xml
            faces-config.xml


xyz-ear


This is the ear module that is the final product to be deployed. Its file structure is as follows:
src
    main
      application
        APP-INF
          classes
            hibernate
               foo.hbm.xml
            spring
               xyzContext.xml
            log4j.properties     
        META-INF
          application.xml
      filters
          filter-dev.properties
      java
pom.xml



The file pom.xml is as follows:
<?xml version="1.0" encoding="UTF-8"?>
       <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
         <modelVersion>4.0.0</modelVersion>
         <parent>
           <artifactId>xyz</artifactId>
           <groupId>com.foo.xyz</groupId>
           <version>1.0</version>
         </parent>
         <artifactId>xyz-ear</artifactId>
         <packaging>ear</packaging>
         <version>1.0</version>
         <name>xyz-ear</name>
        
         
           <build>
             <finalName>xyz</finalName>
             <filters>
              <filter>${basedir}/src/main/filters/filter-${env}.properties</filter>
             </filters>
           
             <plugins>
               <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-ear-plugin</artifactId>
                <version>2.4.2</version>
       
                 <!-- configuring the ear plugin -->
                 <configuration>
                    <filtering>true</filtering>
                   <defaultLibBundleDir>APP-INF/lib</defaultLibBundleDir>
       
                   <modules>
                     <webModule>
                       <groupId>com.foo.xyz</groupId>
                       <artifactId>xyz-web</artifactId>
                     </webModule>
                     <ejbModule>
                       <groupId>com.foo.xyz</groupId>
                       <artifactId>xyz-ejb</artifactId>
                     </ejbModule>
                     
                     <jarModule>
                         <groupId>weblogic</groupId>
                         <artifactId>weblogic</artifactId>
                         <excluded>true</excluded>
               </jarModule>
                   </modules>
                 </configuration>
               </plugin>
               
             <plugin>
         <groupId>scm.plugins</groupId>
                <artifactId>scm-wls-plugin</artifactId>
                <configuration>
         <deployName>xyz</deployName>
         <deploymentName>xyzWLdeploy</deploymentName>
         <artifactPath>C:\workshop\xyz\mavenxyz\xyz-ear\target\xyz.ear</artifactPath>
         <adminServerHostName>localhost</adminServerHostName>
         <adminServerPort>7001</adminServerPort>
         <adminServerProtocol>t3</adminServerProtocol>
         <userId>weblogic</userId>
         <password>weblogic1</password>
         <targetNames>xyzAdminServer</targetNames>
         <verbose>false</verbose>
         <debug>false</debug>
         <upload>true</upload>
         <remote>true</remote>
         </configuration>
               </plugin>
          
             </plugins>
           </build>
           
           <dependencies>
                 <!-- web and ejb modules -->
                 <dependency>
                   <groupId>com.foo.xyz</groupId>
                   <artifactId>xyz-ejb</artifactId>
                   <version>1.0</version>
                   <type>ejb</type>
                 </dependency>
                 <dependency>
                   <groupId>com.foo.xyz</groupId>
                   <artifactId>xyz-web</artifactId>
                   <version>1.0</version>
                   <type>war</type>
                 </dependency>
                 
                 <dependency>
                <groupId>com.foo.xyz</groupId>
                <artifactId>xyz-common-test</artifactId>
                <version>1.0</version>
          </dependency>
       
          <dependency>
            <groupId>antlr</groupId> 
            <artifactId>antlr</artifactId> 
            <version>2.7.6</version> 
          </dependency>
      
       </dependencies>
         
       </project>
  

The file application.xml is the following:
<?xml version="1.0" encoding="UTF-8"?>
   <application xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.4">
 
   <display-name>XYZ</display-name>
     <module>
       <ejb>xyz-ejb-1.0.jar</ejb>
     </module>
     <module>
       <web>
         <web-uri>xyz-web-1.0.war</web-uri>
         <context-root>xyz</context-root>
       </web>
     </module>
   </application>
Notes:
  1. The scm-wls-plugin plugin in the pom is a customer-made plugin.
  2. The generated ear will contain all the dependent jars in the xyz-common module and put them into the directory APP-INF/lib. If you do not want some of them to be included, use "<excluded>true</excluded>" in the jarModule as is the case for weblogic.jar in the above pom file.
  3. If additional jars are needed for the ear, just add them in <dependencies>.
  4. By configuing filtering to be true in the maven-ear-plugin, it will filter files in the
    application directory.

After the ear is built successfully, the exploded ear has the following file structure.
xyz
    APP-INF
        classes
            hibernate
                foo.hbm.xml
            spring
            xyzContext.xml
            log4j.properties
        lib
            antlr-2.7.6.jar
            other_jars from the xyz-common dependencies
    META-INF
        application.xml
    xyz-ejb-1.0.jar
    xyz-web-1.0.war

2 comments:

  1. Thanks for posting this! Helped out a lot while trying to organize my EAR project.

    Ben

    ReplyDelete
  2. xyz
    APP-INF
    classes ---Not able to get *.class from War module
    ---Need xx.xx.xx
    xyz1.class
    xyz2.class
    ----------
    ----------
    xyzn.class

    hibernate
    foo.hbm.xml
    spring
    xyzContext.xml
    log4j.properties
    lib
    antlr-2.7.6.jar
    other_jars from the xyz-common dependencies
    META-INF
    application.xml
    xyz-ejb-1.0.jar
    xyz-web-1.0.war

    ReplyDelete