How to minify javascript and css files using maven plugin

It is advisable that all the production javascript and css files are minified and most of the javascript libraries do this. This post explains how to minify javascript and css files using maven plugin.I have minified sample javascript and css files using minify-maven-plugin. This sample application uses 1.7.2 version of minify-maven-plugin which requires jdk 7 so it does not work with jdk 6 or prior versions.

In this sample application, I have used embedded jetty web container so minification can be tested from browser as well. Please note that I have tested this sample application on windows with jdk 7 64 bit and maven 3.0.4.

This application contains two sample javascript and two sample css files which will be minified using minify-maven-plugin.

sample1.css

H1 {
	color: white;
	background: teal;
	FONT-FAMILY: arial, helvetica, lucida-sans, sans-serif;
	FONT-SIZE: 18pt;
	FONT-STYLE: normal;
	FONT-VARIANT: normal
}
H2 {
	COLOR: #000000;
	FONT-FAMILY: lucida-sans, sans-serif;
	FONT-SIZE: 12pt;
	FONT-STYLE: normal;
	FONT-VARIANT: normal
}

sample2.css

body {
	COLOR: #000000;
	FONT-FAMILY: lucida-sans, sans-serif; FONT-SIZE: 18pt;
	FONT-STYLE: normal;
	FONT-VARIANT: normal;
	background-color:yellow;
}

Above two sample css files are placed under the $sample-web-appsrcmainwebappstyles.

sample1.js

function popupFromSample1() {
	alert("Hello World from sample 1");
}

sample2.js

function popupFromSample2() {
	alert("Hello World from sample 2");
}

Above two sample javascript files are placed under the $sample-web-app\src\main\webapp\scripts.

I have also created index.jsp page as below to test minified javascripts and css files.

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">

<link rel="stylesheet" type="text/css" href="/styles/minified/sample1.css" />
<link rel="stylesheet" type="text/css" href="/styles/minified/sample2.css" />

<script type="text/javascript" src="/scripts/minified/sample1.js"></script>
<script type="text/javascript" src="/scripts/minified/sample2.js"></script>

<html>
	<body>
		<H1>Header 1!</H1>
		<H2>Header 2!</H2>

		Something in body

		<button type="button" onclick="popupFromSample1()">Try popup from sample1.js</button>
		<button type="button" onclick="popupFromSample2()">Try popup from sample2.js</button>
	</body>
</html>

Refer following pom.xml.

<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.elitejavacoder</groupId>
<artifactId>sample-web-app</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>Sample Maven Web App</name>
<url>http://maven.apache.org</url>

	<build>
		<finalName>sample-web-app</finalName>
		<plugins>
			<plugin>
				<groupId>org.mortbay.jetty</groupId>
				<artifactId>maven-jetty-plugin</artifactId>
				<version>6.1.15</version>
				<configuration>
					<contextPath>/</contextPath>
					<scanIntervalSeconds>2</scanIntervalSeconds>
					<webAppSourceDirectory>${basedir}/target/sample-web-app</webAppSourceDirectory>
				</configuration>
			</plugin>

			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-war-plugin</artifactId>
				<version>2.4</version>
				<configuration>
					<warSourceExcludes>/styles/*.css,/scripts/*.js</warSourceExcludes>
				</configuration>
			</plugin>

			<plugin>
				<groupId>com.samaxes.maven</groupId>
				<artifactId>minify-maven-plugin</artifactId>                   
				<version>1.7.2</version>
				<executions>
					<execution>
						<id>minify</id>
						<phase>process-resources</phase>
						<goals>
							<goal>minify</goal>
						</goals>
						<configuration>
							<charset>utf-8</charset>
							<jsEngine>CLOSURE</jsEngine>
							<skipMerge>true</skipMerge>
							<nosuffix>true</nosuffix>

							<cssSourceDir>styles</cssSourceDir>
							<cssTargetDir>styles/minified</cssTargetDir>
							<cssSourceIncludes>
								<cssSourceInclude>*.css</cssSourceInclude>
							</cssSourceIncludes>

							<jsSourceDir>scripts</jsSourceDir>
							<jsTargetDir>scripts/minified</jsTargetDir>
							<jsSourceIncludes>
								<jsSourceInclude>*.js</jsSourceInclude>
							</jsSourceIncludes>
						</configuration>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</project>

In the above pom.xml, minify-maven-plugin is the only plugin required and responsible for minification of javascript and css files. maven-jetty-plugin is used to test this application with jetty web container and maven-war-plugin is used to exclude original javascript and css files from the packaged WAR file.

Take a look at the configuration provided for minify-maven-plugin. I have created minified files in a separate directory (refer <cssTargetDir> and <jsTargetDir> elements) as I don’t want any suffix to be added to minified files. I have specified <nosuffix>true</nosuffix> so name of minified file remains same as source file otherwise it creates *.min.css or *.min.js (i.e. sample1.min.css, sample1.min.css).

I have specified <cssTargetDir> and <jsTargetDir> for resultant minified files otherwise minified files are created in the same directory as source file. Please be informed that <nosuffix> with true value won’t create minified files if target directory is not specified, to avoid file overwriting issue.

In the above sample pom file, I have minified all the javascript and css files available in the directory however you can minify some specific files as described below (replace <cssSourceIncludes> element with the following).

<cssSourceFiles>
	<cssSourceFile>sample1.css</cssSourceFile>
	<cssSourceFile>sample2.css</cssSourceFile>
</cssSourceFiles>

<jsSourceFiles>
	<jsSourceFile>sample1.js</jsSourceFile>
	<jsSourceFile>sample2.js</jsSourceFile>
</jsSourceFiles>

One more thing, note that I have specified true for the <skipMerge>true</skipMerge> which stops the plugin to create one single(one merged file for css and one for javascript) file by combining all the files in one. The default value for skipMerge is false so it creates one style.css for all the css files and one script.js file for all the javascript files. If you do not like these names then you can specify merged file names of your choice using jsFinalFile and cssFinalFile element under plugin configuration.

Now run the mvn clean install –DskipTests from command propmpt, check your generated war file. It should have minified javascript and css files.

Run application in Jetty and test from the browser.

Run mvn jetty:run command from command prompt from project base directory. It deploys war file to embedded web container and which will be accessible at http://127.0.0.1:8080/index.jsp.

Now you can check that javascripts and css are minified or not by accessing the following urls.

http://127.0.0.1:8080/styles/minified/sample1.css – Returns minified css as below:

H1{color:white;background:teal;FONT-FAMILY:arial,helvetica,lucida-sans,sans-serif;FONT-SIZE:18pt;FONT-STYLE:normal;FONT-VARIANT:normal}H2{COLOR:#000;FONT-FAMILY:lucida-sans,sans-serif;FONT-SIZE:12pt;FONT-STYLE:normal;FONT-VARIANT:normal}

http://127.0.0.1:8080/styles/minified/sample2.css – Returns minified css as below:

body{COLOR:#000;FONT-FAMILY:lucida-sans,sans-serif;FONT-SIZE:18pt;FONT-STYLE:normal;FONT-VARIANT:normal;background-color:yellow}

http://127.0.0.1:8080/scripts/minified/sample1.js – Returns minified javascript as below:

function popupFromSample1(){alert("Hello World from sample 1")};

http://127.0.0.1:8080/scripts/minified/sample2.js – Returns minified javascript as below:

function popupFromSample2(){alert("Hello World from sample 2")};

If you have any query on this then feel free to ask me by putting comment below.

Sample application is available on GitHub at https://github.com/elitejavacoder/maven-minify-javascript-and-css

Maven – Run web project in Jetty

Jetty has a slogan, “Don’t deploy your application in Jetty, deploy Jetty in your application.” and that is really amazing thing specially when we are in development phase. It makes developer’s life more easy. In this post I will explain you how to run jetty web server in your web application. I will create a sample web application and then I will run that application in jetty by embedding jetty in application. I will use maven-jetty-plugin to demonsrate this.

Sample web application

Create one directory in your file system. In my case I have created directory with name “sample-web-app” in my file system.

Create pom.xml under root directory (i.e. under sample-web-app directory) as described 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/maven-v4_0_0.xsd">

	<modelVersion>4.0.0</modelVersion>
	<groupId>com.elitejavacoder</groupId>
	<artifactId>sample-web-app</artifactId>
	<packaging>war</packaging>
	<version>1.0-SNAPSHOT</version>
	<name>Sample Maven Web App</name>
	<url>http://maven.apache.org</url>

	<build>
		<finalName>sample-web-app</finalName>
		<plugins>
			<plugin>
				<groupId>org.mortbay.jetty</groupId>
				<artifactId>maven-jetty-plugin</artifactId>
				<version>6.1.15</version>

				<configuration>
					<contextPath>/</contextPath>
					<scanIntervalSeconds>2</scanIntervalSeconds>
					<webAppSourceDirectory>${basedir}/target/sample-web-app</webAppSourceDirectory>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

Create web.xml file under $sample-web-appsrcmainwebappWEB-INF as described below.


Jetty test web application

Create sample index.jsp file under $sample-web-appsrcmainwebapp directory as below.

<html>
	<body>
		<h2>Hello World - This page is served by Jetty!</h2>
	</body>
</html>

Run following maven command from your root directory (i.e. sample-web-app directory) to build your application.

mvn clean install

Run web application with Jetty

Now run following maven command from your root directory (i.e. sample-web-app directory) to start jetty with your application.

mvn jetty:run

Now access “http://127.0.0.1:8080/index.jsp” url from your browser which will display content of index.jsp page we have created as below.

Hot deployment with Jetty

Now update sample index.jsp file which we have created under $sample-web-appsrcmainwebapp directory as below.

<html>
	<body>
		<h2>Hello World - This page is served by Jetty!</h2>
		<h2>Testing hot deployment</h2>
	</body>
</html>

Now access “http://127.0.0.1:8080/index.jsp” url from your browser which will display updated content of index.jsp page as below without restarting the server.

Replace property values at the time of maven build

This post explains how to replace property values at the time of maven build.

Replace property value in resource files (non-java files) at the time of maven build

Create one resource file filter-test.txt in $PROJECT_HOME/src/main/resources with content as follow.

Hello ${resource.name}

Now add following lines in pom.xml file of your project.

 
<properties>
	<resource.name>RESOURCE</resource.name>
</properties>

<build>  
	<resources>
		<!-- Filter resource files -->
		<resource>
			<directory>src/main/resources</directory>
			<filtering>true</filtering>
		</resource>
	</resources>
	....
</build>

Build your project using following command.

mvn clean install

Check content of filter-test.txt file under $PROJECT_HOME/target/classes. It should be as follow.

Hello RESOURCE

Please note that at the time of build ${resource.name} in filter-test.txt file is replaced with “RESOURCE” which we have defined in pom.xml file as property.

Now you can overwrite property value defined in pom.xml file using command line argument at the time of build. Do build using following command.

mvn clean install -Dresource.name=Atul

Check content of the filter-test.txt file under $PROJECT_HOME/target/classes. It should be as follow.

Hello Atul

Replace property value in java files at the time of maven build

Create one FilterTest.java file under $PROJECT_HOME/src/main/java/com/elitejavacoder/test with content as follow.

package com.elitejavacoder.test;

public class FilterTest {

	private static String NAME = "${java.name}";

		public static void main(String[] args) {

		try {
			System.out.println("n Value of name : " + NAME);
		}
		catch (Exception ex) {
			ex.printStackTrace();
		}
	}
}

Now add following lines in pom.xml file of your project.

<properties>
	<java.name>JAVA</java.name>
</properties>

<build>  
	<resources>
		<!-- Filter Java files -->
		<resource>
			<filtering>true</filtering>
			<directory>src/main/java</directory>
			<targetPath>../filtered-sources/java</targetPath>
			<includes>
				<include>**/*.java</include>
			</includes>
		</resource>
	</resources>

	<!-- change default source directory to filtered-sources/java -->
	<sourceDirectory>target/filtered-sources/java</sourceDirectory>
	....
</build>

Please note that in case of java files, we filter java files as resource files and copy them to filtered-sources/java. Then we change default maven source directory to point filtered java files directory using <sourceDirectory>.

Now do a build using following command.

mvn clean install

Run this class to check output. Please note that I have created executable jar so I will run this class using following command from $PROJECT_HOME/target. For information on how to create executable jar please refer this post.

java -jar replace-property-values-at-build-time-1.0.0-SNAPSHOT.jar

The output should be as follow.

Value of name : JAVA

Please note that at the time of maven build, ${java.name} in FilterTest.java is replaced with “JAVA” which we have defined in pom.xml file as property. You can check this in compiled class file as well using any decompiler.

Now you can overwrite this property value defined in pom.xml file using command line argument at the time of build. Do build using following command.

mvn clean install -Djava.name=Atul

Again run this class to check output using following command.

java -jar replace-property-values-at-build-time-1.0.0-SNAPSHOT.jar

The output should be as follow.

Value of name : Atul

I hope this post helps!

How to create executable jar with maven

This post explain you how to create executable jar file with maven.

Here i used maven-jar-plugin to create executable jar files. Please refer following pom.xml.

<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" 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.elitejavacoder</groupId>
	<artifactId>commons</artifactId>
	<packaging>jar</packaging>
	<name>commons</name>
	<version>1.0.0-SNAPSHOT</version>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-jar-plugin</artifactId>
				<version>2.2</version>
				<configuration>
					<archive>
						<manifest>
							<addClasspath>true</addClasspath>
							<mainClass>com.elitejavacoder.MainClass</mainClass>
						</manifest>
					</archive>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

Change com.elitejavacoder.MainClass with your fully qualified class name of your main class.

Now build your project using mvn clean install command.

Check MANIFEST.MF file under the META-INF directory inside jar file. It should contain following entry.

Main-Class: com.elitejavacoder.MainClass (in your case fully qualified class name of your main class).

Now you can run this jar file using following command from command prompt.

java -jar commons-1.0.0-SNAPSHOT.jar

Sample J2EE application using maven

In this post I will show you how to set up a sample J2EE application using maven which contains WAR, EJB-JAR and one dependent utility JAR.

  • Create a directory MavenTestProject (You can name it whatever you like) somewhere in your file system. Now onwards I will refer it as $PROJECT_ROOT_FOLDER. Now follow the below steps to create sample j2ee project using maven.

package com.elitejavacoder.common;

import java.text.SimpleDateFormat;
import java.util.Date;

public class DateUtil {
	private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");

	public static String getFormattedDateString(Date date) {
		String formattedDate = null;

		try {
			if (date != null) {
				formattedDate = DATE_FORMAT.format(date);
			}
		}
		catch (Exception ex) {
			ex.printStackTrace();
		}
		return formattedDate;
	}
}

  • Create pom.xml file inside $PROJECT_ROOT_FOLDERcommons.

	<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" 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.elitejavacoder</groupid>
		<artifactid>commons</artifactid>
		<packaging>jar</packaging>
		<name>commons</name>
		<version>1.0-SNAPSHOT</version>

	</project>

  • Create stateless session bean TestSessionBean.java inside $PROJECT_ROOT_FOLDERenterprisesrcmainjavacomelitejavacoderejb.

package com.elitejavacoder.ejb;

import javax.ejb.Local;
import javax.ejb.Remote;
import javax.ejb.Stateless;

import java.util.Date;

import com.elitejavacoder.common.DateUtil;

@Stateless
@Local(TestSessionLocal.class)
@Remote(TestSessionRemote.class)
	public class TestSessionBean {

		public TestSessionBean() {
		}

		public String getGreetings(String name) {
			return "Hello " + name + "! Current time is " + DateUtil.getFormattedDateString(new Date());
		}
	}

  • Create remote interface TestSessionRemote.java inside $PROJECT_ROOT_FOLDERenterprisesrcmainjavacomelitejavacoderejb.

	package com.elitejavacoder.ejb;

	public interface TestSessionRemote {
		public String getGreetings(String name);
	}

  • Create local interface TestSessionLocal.java inside $PROJECT_ROOT_FOLDERenterprisesrcmainjavacomelitejavacoderejb.

	package com.elitejavacoder.ejb;

	public interface TestSessionLocal {
		public String getGreetings(String name);
	}

  • Create pom.xml file inside $PROJECT_ROOT_FOLDERenterprise.

	<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" 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.elitejavacoder</groupid>
		<artifactid>enterprise</artifactid>
		<packaging>jar</packaging>
		<name>enterprise</name>
		<version>1.0-SNAPSHOT</version>

	<dependencies>
		<dependency>
			<groupid>javax</groupid>
			<artifactid>javaee-api</artifactid>
			<version>6.0</version>
		</dependency>

		<dependency>
			<groupid>com.elitejavacoder</groupid>
			<artifactid>commons</artifactid>
			<version>1.0-SNAPSHOT</version>
			<type>jar</type>
		</dependency>
	</dependencies>

		<build>
			<defaultgoal>package</defaultgoal>
			<plugins>
				<plugin>
					<artifactid>maven-ejb-plugin</artifactid>
					<configuration>
						<archive>
						<manifest>
							<addclasspath>true</addclasspath>
						</manifest>
						</archive>
					</configuration>
				</plugin>
			</plugins>  
		</build>
	</project>

  • Create one simple servlet inside $PROJECT_ROOT_FOLDERwebsrcmainjavacomelitejavacoderweb directory.

package com.elitejavacoder.web;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import javax.naming.InitialContext;
import javax.naming.NamingException;

import com.elitejavacoder.ejb.TestSessionRemote;

public class TestServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		processRequest(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		processRequest(request, response);
	}

	protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		try {
			String name = "Atul";
			if (request.getParameter("name") != null) {
				name = request.getParameter("name");
			}

			response.setContentType("text/html");
			PrintWriter out = response.getWriter();

			out.println("");
			out.println("");
			out.println(" Greetings ");
			out.println("");
			out.println("");
			out.println("<h1>" + getGreetings(name) + "</h1>");
			out.println("");
			out.println("");
			out.close();
		}
		catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	public String getGreetings(String name) {
		try {
			TestSessionRemote testSessionRemote = (TestSessionRemote)new InitialContext().lookup("java:app/enterprise-1.0-SNAPSHOT/TestSessionBean!com.elitejavacoder.ejb.TestSessionRemote");
			return testSessionRemote.getGreetings(name);
		}
		catch (Exception ex) {
			ex.printStackTrace();
		}
		return name;
	}
}

  • Create index.jsp inside $PROJECT_ROOT_FOLDERwebsrcmainwebapp directory.

<h2>
	Sample J2EE project using Maven</h2>
	<form action="/testservlet" method="POST">
		Your name: <input name="name" type="text">

		<input value="Submit" type="submit">
	</form>

  • Create web.xml inside $PROJECT_ROOT_FOLDERwebsrcmainwebappWEB-INF directory.

	<web -app="-app" version="3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemalocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
		<servlet>
			<servlet -name="-name">TestServlet</servlet>
			<servlet -class="-class">com.elitejavacoder.web.TestServlet</servlet>
		</servlet>

		<servlet -mapping="-mapping">
			<servlet -name="-name">TestServlet</servlet>
			<url -pattern="-pattern">/testservlet</url>
		</servlet>
	</web>

  • Create pom.xml file inside $PROJECT_ROOT_FOLDERweb directory.

<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" 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.elitejavacoder</groupid>
	<artifactid>web</artifactid>
	<packaging>war</packaging>
	<name>web</name>
	<version>1.0-SNAPSHOT</version>
	 
	<dependencies>
		<dependency>
			<groupid>javax</groupid>
			<artifactid>javaee-api</artifactid>
			<version>6.0</version>
		</dependency>
	   
		<dependency>
			<groupid>com.elitejavacoder</groupid>
			<artifactid>enterprise</artifactid>
			<version>1.0-SNAPSHOT</version>
			<type>jar</type>
		</dependency>
	</dependencies>
	 
	<build>
		<defaultgoal>package</defaultgoal>

		<plugins>
			<plugin>
				<groupid>org.apache.maven.plugins</groupid>
				<artifactid>maven-war-plugin</artifactid>
				<version>2.1-alpha-2</version>
				<configuration>
					<webresources>
						<resource>
							<directory>./src/main/webapp</directory>
						</resource>
					</webresources>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

  • Create pom.xml inside $PROJECT_ROOT_FOLDERdeploy directory create deployable EAR file by packaging all the above artifacts.

	<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" 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.elitejavacoder</groupid>
		<artifactid>deploy</artifactid>
		<packaging>ear</packaging>
		<name>deploy</name>
		<version>1.0-SNAPSHOT</version>

		<dependencies>
			<dependency>
				<groupid>com.elitejavacoder</groupid>
				<artifactid>enterprise</artifactid>
				<version>1.0-SNAPSHOT</version>
				<type>ejb</type>
			</dependency>

			<dependency>
				<groupid>com.elitejavacoder</groupid>
				<artifactid>web</artifactid>
				<version>1.0-SNAPSHOT</version>
				<type>war</type>
			</dependency>
		</dependencies>

		<build>
			<defaultgoal>package</defaultgoal>
			<plugins>
				<plugin>
					<artifactid>maven-ear-plugin</artifactid>
					<version>2.4.1</version>
					<configuration>
						<version>6</version>
						<finalname>MavenTestProject</finalname>
						<defaultlibbundledir>lib/</defaultlibbundledir>
						<modules>
							<ejbmodule>
								<groupid>com.elitejavacoder</groupid>
								<artifactid>enterprise</artifactid>
								<bundledir>/</bundledir>
							</ejbmodule>
							<webmodule>
								<groupid>com.elitejavacoder</groupid>
								<artifactid>web</artifactid>
								<contextroot>/</contextroot>
							</webmodule>
						</modules>
					</configuration>
				</plugin>
			</plugins>  
		</build>
	</project>

  • Now create parent pom.xml file inside $PROJECT_ROOT_FOLDER.

<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" 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.elitejavacoder</groupid>
	<artifactid>parent</artifactid>
	<packaging>pom</packaging>
	<name>Maven Test Project</name>
	<version>1.0-SNAPSHOT</version>

	<modules>
		<module>commons</module>
		<module>enterprise</module>
		<module>web</module>
		<module>deploy</module>
	</modules>
</project>

  • Now open command prompt and go to $PROJECT_ROOT_FOLDER. Type mvn clean install and press enter. Once the build is completed successfully project EAR file MavenTestProject.ear will be available inside $PROJECT_ROOT_FOLDERdeploytarget.

    Deploy this MavenTestProject.ear file. Open http://localhost:8080/index.jsp url in you browser, type your name and hit the submit. In response you will get a greetings message with current date and time from application.