šŸ“¦ How to Create EAR File Using Maven?

• Originally published on old blog

Note: This post was originally published in 2013. While Maven remains a fundamental build tool, modern Java development often uses Gradle or cloud-native approaches. However, the principles of multi-module project management remain relevant.

It's much easier to create and understand the creation process of JAR, WAR using Maven build tool. But creation of Enterprise application is a bit confusing and yet a bit interesting too with the use of the "Reactor" plugin!

Just hang on with us for a while to know how to create EAR file using Maven build management tool.

Implementation Part

Step 1: Project Structure

Consider the following scenario; in my cricket project, I have developed three different types of Applications:

  • myearproject-dhoni-web – We need to bundle this as a separate WAR file using its own pom.xml
  • myearproject-dravid-web – We need to bundle this as a separate WAR file using its own pom.xml
  • myearproject-sachin-web – We need to bundle this as a separate WAR file using its own pom.xml

Step 2: Generate WAR Files

Once this WAR files generation is completed for all 3 modules, finally we need to put it all together and generate an EAR file. Refer to the following diagram for reference.

Project Structure:

myearproject/
ā”œā”€ā”€ pom.xml (parent)
ā”œā”€ā”€ myearproject-ear/
│   └── pom.xml (EAR module)
ā”œā”€ā”€ myearproject-dhoni-web/
│   └── pom.xml (WAR module)
ā”œā”€ā”€ myearproject-dravid-web/
│   └── pom.xml (WAR module)
└── myearproject-sachin-web/
    └── pom.xml (WAR module)

Step 3: Project Aggregation

Here we have a separate pom.xml file for individual projects which would perform WAR file generation. And finally, we need to create a special project called "multi-module project" in Maven terms. It will not create any JAR or WAR artifacts, it just aggregates all other projects as "Modules".

Multi-Module Project POM File

Parent POM file that aggregates all modules:

<?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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany</groupId>
  <artifactId>myearproject</artifactId>
  <packaging>pom</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>myearproject Maven Enterprise Application</name>
  <url>http://maven.apache.org</url>
  <modules>
    <module>myearproject-ear</module>
    <module>myearproject-sachin-web</module>
    <module>myearproject-dravid-web</module>
    <module>myearproject-dhoni-web</module>
  </modules>
</project>

Module I: myearproject-dhoni-web

WAR module for Dhoni web application:

<?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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <artifactId>myearproject</artifactId>
        <groupId>com.mycompany</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <groupId>com.mycompany</groupId>
    <artifactId>myearproject-dhoni-web</artifactId>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>myearproject-dhoni-web</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>6.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
</project>

Module II: myearproject-dravid-web

WAR module for Dravid web application:

<?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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <artifactId>myearproject</artifactId>
        <groupId>com.mycompany</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <groupId>com.mycompany</groupId>
    <artifactId>myearproject-dravid-web</artifactId>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>myearproject-dravid-web</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>6.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
</project>

Module III: myearproject-sachin-web

WAR module for Sachin web application:

<?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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <artifactId>myearproject</artifactId>
        <groupId>com.mycompany</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <groupId>com.mycompany</groupId>
    <artifactId>myearproject-sachin-web</artifactId>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>myearproject-sachin-web</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>6.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
</project>

Module IV: myearproject-ear

EAR module that packages all WAR files:

<?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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <artifactId>myearproject</artifactId>
        <groupId>com.mycompany</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <groupId>com.mycompany</groupId>
    <artifactId>myearproject-ear</artifactId>
    <packaging>ear</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>myearproject-ear</name>
    <url>http://maven.apache.org</url>
    
    <dependencies>
        <!-- WAR dependencies -->
        <dependency>
            <groupId>com.mycompany</groupId>
            <artifactId>myearproject-dhoni-web</artifactId>
            <version>1.0-SNAPSHOT</version>
            <type>war</type>
        </dependency>
        <dependency>
            <groupId>com.mycompany</groupId>
            <artifactId>myearproject-dravid-web</artifactId>
            <version>1.0-SNAPSHOT</version>
            <type>war</type>
        </dependency>
        <dependency>
            <groupId>com.mycompany</groupId>
            <artifactId>myearproject-sachin-web</artifactId>
            <version>1.0-SNAPSHOT</version>
            <type>war</type>
        </dependency>
    </dependencies>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-ear-plugin</artifactId>
                <version>3.2.0</version>
                <configuration>
                    <finalName>myearproject</finalName>
                    <applicationName>myearproject</applicationName>
                    <initializeInOrder>true</initializeInOrder>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Application.xml Configuration

Create the application.xml file in the EAR module's src/main/application/META-INF/ directory:

<?xml version="1.0" encoding="UTF-8"?>
<application 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/application_6.xsd"
             version="6">
    <display-name>myearproject</display-name>
    <description>My Enterprise Application</description>
    
    <!-- Web modules -->
    <module>
        <web>
            <web-uri>myearproject-dhoni-web-1.0-SNAPSHOT.war</web-uri>
            <context-root>/dhoni</context-root>
        </web>
    </module>
    
    <module>
        <web>
            <web-uri>myearproject-dravid-web-1.0-SNAPSHOT.war</web-uri>
            <context-root>/dravid</context-root>
        </web>
    </module>
    
    <module>
        <web>
            <web-uri>myearproject-sachin-web-1.0-SNAPSHOT.war</web-uri>
            <context-root>/sachin</context-root>
        </web>
    </module>
</application>

Build Commands

Commands to build the entire project:

# Build all modules
mvn clean install

# Build only the EAR module
mvn clean install -pl myearproject-ear

# Build with specific profile
mvn clean install -Pproduction

# Build with debug information
mvn clean install -X

Advanced EAR Configuration

Enhanced EAR plugin configuration with additional options:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-ear-plugin</artifactId>
    <version>3.2.0</version>
    <configuration>
        <finalName>myearproject</finalName>
        <applicationName>myearproject</applicationName>
        <initializeInOrder>true</initializeInOrder>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <classpathPrefix>lib/</classpathPrefix>
            </manifest>
        </archive>
        
        <!-- Web module configuration -->
        <webModule>
            <groupId>com.mycompany</groupId>
            <artifactId>myearproject-dhoni-web</artifactId>
            <contextRoot>/dhoni</contextRoot>
        </webModule>
        <webModule>
            <groupId>com.mycompany</groupId>
            <artifactId>myearproject-dravid-web</artifactId>
            <contextRoot>/dravid</contextRoot>
        </webModule>
        <webModule>
            <groupId>com.mycompany</groupId>
            <artifactId>myearproject-sachin-web</artifactId>
            <contextRoot>/sachin</contextRoot>
        </webModule>
        
        <!-- Security configuration -->
        <security>
            <securityRole>
                <roleName>admin</roleName>
                <principalName>admin</principalName>
            </securityRole>
        </security>
    </configuration>
</plugin>

Multi-Module Project Best Practices

  • Parent POM: Define common properties and dependencies in parent POM
  • Version Management: Use dependency management for consistent versions
  • Module Order: Ensure proper build order with dependencies
  • Profiles: Use Maven profiles for different environments
  • Testing: Include integration tests for EAR deployment
  • Documentation: Document module dependencies and relationships

Parent POM with Dependency Management

Enhanced parent POM with dependency management:

<?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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany</groupId>
  <artifactId>myearproject</artifactId>
  <packaging>pom</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>myearproject Maven Enterprise Application</name>
  <url>http://maven.apache.org</url>
  
  <properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <javaee.version>6.0</javaee.version>
    <maven-ear-plugin.version>3.2.0</maven-ear-plugin.version>
  </properties>
  
  <modules>
    <module>myearproject-ear</module>
    <module>myearproject-sachin-web</module>
    <module>myearproject-dravid-web</module>
    <module>myearproject-dhoni-web</module>
  </modules>
  
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-web-api</artifactId>
        <version>${javaee.version}</version>
        <scope>provided</scope>
      </dependency>
      <dependency>
        <groupId>com.mycompany</groupId>
        <artifactId>myearproject-dhoni-web</artifactId>
        <version>${project.version}</version>
        <type>war</type>
      </dependency>
      <dependency>
        <groupId>com.mycompany</groupId>
        <artifactId>myearproject-dravid-web</artifactId>
        <version>${project.version}</version>
        <type>war</type>
      </dependency>
      <dependency>
        <groupId>com.mycompany</groupId>
        <artifactId>myearproject-sachin-web</artifactId>
        <version>${project.version}</version>
        <type>war</type>
      </dependency>
    </dependencies>
  </dependencyManagement>
  
  <build>
    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-ear-plugin</artifactId>
          <version>${maven-ear-plugin.version}</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

Deployment Configuration

Example deployment configuration for different application servers:

WebLogic Deployment

# WebLogic deployment command
java weblogic.Deployer -adminurl t3://localhost:7001 -username weblogic -password weblogic123 -deploy -name myearproject -source myearproject-ear/target/myearproject.ear

JBoss Deployment

# JBoss deployment command
cp myearproject-ear/target/myearproject.ear /opt/jboss/standalone/deployments/

Modern Alternatives

While Maven EAR projects are still valid, modern alternatives include:

  • Microservices: Deploy individual WAR files as separate services
  • Docker Containers: Containerize each web application
  • Kubernetes: Orchestrate microservices with Kubernetes
  • Spring Boot: Use embedded containers instead of EAR deployment
  • Cloud Platforms: Deploy to cloud platforms like AWS, Azure, GCP
  • Gradle: Use Gradle for more flexible build configuration

Troubleshooting

Common issues and solutions:

  • Classpath Issues: Ensure proper classpath configuration in application.xml
  • Version Conflicts: Use dependency management to resolve conflicts
  • Build Order: Verify module dependencies and build order
  • Deployment Failures: Check application server logs for deployment errors
  • Context Root Conflicts: Ensure unique context roots for web modules

Key Takeaways

  • Maven multi-module projects enable complex enterprise application packaging
  • EAR files provide a way to deploy multiple web applications as a single unit
  • Proper dependency management is essential for successful builds
  • Application.xml configuration defines the deployment structure
  • Modern alternatives offer more flexibility and scalability