Packaging WAR, JAR modules into EAR using Maven Build Tool

Introduction

Here you will see the process of packaging WAR, JAR modules into EAR file. EAR, also known as, Enterprise Archive, in which all files (.jar and .war) are packaged as JAR file with .ear (enterprise archive) extension and deployed into Application Server.

Prerequisites

Java at least 1.8, Maven 3.6.3

WAR, JAR and EAR

EJB modules which contain enterprise java beans (class files) and EJB deployment descriptor are packed as JAR files with .jar extenstion.

Web modules which contain Servlet class files, JSP Files, supporting files, GIF and HTML files are packaged as JAR file with .war (web archive) extension.

An EJB container hosts Enterprise Java beans based on the EJB API designed to provide extended business functionality such as declarative transactions, declarative method level security and multiprotocol support – so more of an RPC style of distributed computing.

EJB containers require EJB modules to be packaged as JAR files and these files have an ejb-jar.xml file in the META-INF folder.

Enterprise applications may consist of one or more modules that can either be Web modules (packaged as a WAR file), EJB modules (packaged as a JAR file), or both of them.

Enterprise applications are packaged as EAR files ― these are special JAR files containing an application.xml file in the META-INF folder.

EAR files are a superset containing WAR files and JAR files. Java Application Servers allow deployment of standalone web modules in a WAR file, though internally, they create EAR files as a wrapper around WAR files.

Standalone web containers such as Tomcat and Jetty do not support EAR files ― these are not full-fledged Application servers. Web applications in these containers need to be deployed as WAR files only.

Enough talking about war, jar and ear files. Now let’s move onto packaging war, jar modules into ear.

Packaging war, jar into ear

Let’s assume you have web module, simple jar module, ejb module etc., which need to be packaged into ear file. I will show here maven based configurations. The <parent/> tag includes the parent pom if there is any. If parent parent is not required for your app then you can remove it.

So your pom file would like similar to below:

<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>
	<parent>
		<groupId>com.example</groupId>
		<artifactId>common</artifactId>
		<version>0.0.1-SNAPSHOT</version>
		<relativePath>../common</relativePath>
	</parent>
	<artifactId>example-ear</artifactId>
	<packaging>ear</packaging>
	<description>Enterprise archive for Sample Application</description>
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-ear-plugin</artifactId>
				<configuration>
					<version>6</version>
					<fileNameMapping>no-version</fileNameMapping>
					<defaultLibBundleDir>lib</defaultLibBundleDir>
					<skinnyWars>true</skinnyWars>
					<applicationName>example-ear</applicationName>
					<displayName>ApplicationEAR</displayName>
					<finalName>example-ear</finalName>
					<modules>
						<webModule>
							<groupId>${project.parent.groupId}</groupId>
							<artifactId>example-web</artifactId>
							<contextRoot>/example</contextRoot>
							<bundleFileName>bookingr-10-web.war</bundleFileName>
						</webModule>
						<ejbModule>
							<groupId>${project.parent.groupId}</groupId>
							<artifactId>example-ejb</artifactId>
						</ejbModule>
						<jarModule>
							<groupId>${project.parent.groupId}</groupId>
							<artifactId>example-jar</artifactId>
							<bundleDir>/</bundleDir>
						</jarModule>
					</modules>
				</configuration>
			</plugin>
		</plugins>
	</build>
	<dependencies>
		<dependency>
			<groupId>${project.parent.groupId}</groupId>
			<artifactId>example-web</artifactId>
			<version>${project.parent.version}</version>
			<type>war</type>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>${project.parent.groupId}</groupId>
			<artifactId>example-ejb</artifactId>
			<version>${project.parent.version}</version>
			<type>ejb</type>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>${project.parent.groupId}</groupId>
			<artifactId>example-jar</artifactId>
			<version>${project.parent.version}</version>
			<type>jar</type>
		</dependency>
	</dependencies>
</project>

I assume the above pom file is in ear module, which will include war, ejb jar and simple jar files. I used maven-ear-plugin for packaging war, jar modules into ear.

Look at the configuration tag, where I define default bundle directory is lib, which will include all the libraries except war and ejb jars.

I have set skinnyWars to true. Now why do you need this tag to be true? In a typical J2EE environment, a WAR is packaged within an EAR for deployment. The WAR can contain all its dependent JARs in WEB-INF/lib but then the EAR can quickly grow very large if there are multiple WARs, due to the presence of duplicate JARs. Instead the J2EE specification allows WARs to reference external JARs packaged within the EAR via the Class-Path setting in their MANIFEST.MF.

Then I include several modules such as webModule, ejbModule, jarModule to include war, ejb jar and jar modules, respectively.

I want war and ejb jar modules to be present inside the ear but outside of lib directory and by default these archives are stored into ear but outside of lib directory.

But other jar files are stored into lib directory inside the ear and in the above file, I do not want to put example-jar inside the lib directory but inside ear. That’s why I have overridden the defaultLibBundleDir using the tag <bundleDir> under <jarModule>.

Now when you build your multi module project, then you will see war, ejb jar and example-jar will be stored into ear but outside the lib directory and all other jar files will be stored into lib directory.

This is all about packaging jar, war into ear module.

Source Code

Download

Leave a Reply

Your email address will not be published. Required fields are marked *