Create Both war and jar Files using Maven

Introduction

This tutorial will show you how to create both war and jar file in an web application using maven. Sometimes you may need to create both war and jar files for an web application using maven build tool because some other standalone project needs to include the jar file for this web application.

For example you can create war and jar files in your Spring Boot applications.

Prerequisites

Java at least 1.8, Maven 3.6.3

Maven Configurations

War Plugin

This is a default goal if you mention your application’s packaging type is war then you need not to add this plugin. So it will build war file.

You need to add maven war plugin into pom.xml file to create an war file for the web application.

In the below plugin I have mentioned goal as inplace that indicates the webapp is generated in web application’s source directory, which is src/main/resources by default.

The value of <attachclasses> configuration is by default false. I have set this field’s value to true to attach classes for the war file.

The value of <webXml> specifies the path of the XML file to use.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <executions>
        <execution>
            <phase>package</phase>
            <configuration>
                <attachClasses>true</attachClasses>
                <webXml>${basedir}/src/main/webapp/WEB-INF/web.xml</webXml>
            </configuration>
            <goals>
                <goal>inplace</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Jar Plugin

This plugin provides capability to build jars.

The goal of this jar plugin is to create a jar file for your project classes inclusive resources.

The phase represents a stage in lifecycle of the build. The phase:compile compiles the source code of the project.

You need maven jar plugin to create a jar file for the web application.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <executions>
        <execution>
            <id>make-a-jar</id>
            <phase>compile</phase>
            <goals>
                <goal>jar</goal>
            </goals>
        </execution>
    </executions>
</plugin>

The above plugin does not add the required dependencies into your jar file. To include all required dependencies in your jar file you can use the following maven-assembly-plugin plugin. If your app does not have any main class then you can omit the <mainClass/> tag.

<plugin>
	<artifactId>maven-assembly-plugin</artifactId>
	<executions>
	 <execution>
		  <phase>package</phase>
		  <goals>
			  <goal>single</goal>
		  </goals>
	  </execution>
	</executions>
	<configuration>
	   <archive>
		   <manifest>
				<addClasspath>true</addClasspath>
				<classpathPrefix>lib/</classpathPrefix>
				<!--<mainClass>fully.qualified.MainClass</mainClass>
-->
		   </manifest>
	   </archive>
	   <descriptorRefs>
		   <descriptorRef>jar-with-dependencies</descriptorRef>
	  </descriptorRefs>
	</configuration>
</plugin>

Install Plugin

The Install Plugin is used during the install phase to add artifact(s) to the local repository. The Install Plugin uses the information in the POM (groupId, artifactId, version) to determine the proper location for the artifact within the local repository.

You need to keep the generated jar file into the build directory. So use the below maven plugin.

<file> indicates the location of the jar file. The file name pattern in this should be according to your jar name otherwise you will see error while installing into the local repository. So use the pattern accordingly.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-install-plugin</artifactId>
    <executions>
        <execution>
            <id>Add-2-local-repository</id>
            <phase>package</phase>
            <configuration>
                <packaging>jar</packaging>
                <!--<file>${project.build.directory}\${project.artifactId}.jar</file>-->
                <file>${project.build.directory}\${artifactId}-${version}.jar</file>
                <!-- <file>${project.build.directory}\${project.artifactId}-jar-with-dependencies.jar</file> -->
            </configuration>
            <goals>
                <goal>install-file</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Maven pom.xml

Putting all together, the entire content of the pom.xml file is given below. I have used Servlet API to show you an example. In place of Servlet API you can have any web based framework.

<?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.roytuts</groupId>
	<artifactId>web-app</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<maven.compiler.source>12</maven.compiler.source>
		<maven.compiler.target>12</maven.compiler.target>
	</properties>

	<dependencies>

		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>4.0.1</version>
			<scope>provided</scope>
		</dependency>

	</dependencies>

	<build>
		<finalName>web-app-global-exceptions</finalName>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.8.1</version>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-war-plugin</artifactId>
				<version>3.3.1</version>
				<executions>
					<execution>
						<phase>package</phase>
						<configuration>
							<attachClasses>true</attachClasses>
							<failOnMissingWebXml>false</failOnMissingWebXml>
							<webXml>${basedir}/src/main/webapp/WEB-INF/web.xml</webXml>
						</configuration>
						<goals>
							<goal>inplace</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
			<!--<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-jar-plugin</artifactId>
				<version>3.2.0</version>
				<executions>
					<execution>
						<id>make-a-jar</id>
						<phase>compile</phase>
						<goals>
							<goal>jar</goal>
						</goals>
					</execution>
				</executions>
			</plugin>-->
			<plugin>
                 <artifactId>maven-assembly-plugin</artifactId>
                 <executions>
                     <execution>
                          <phase>package</phase>
                          <goals>
                              <goal>single</goal>
                          </goals>
                      </execution>
                  </executions>
                  <configuration>
                       <archive>
                           <manifest>
                           		<addClasspath>true</addClasspath>
                        		<classpathPrefix>lib/</classpathPrefix>
                                 <mainClass>fully.qualified.MainClass</mainClass>
                           </manifest>
                       </archive>
                       <descriptorRefs>
                           <descriptorRef>jar-with-dependencies</descriptorRef>
                      </descriptorRefs>
                 </configuration>
            </plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-install-plugin</artifactId>
				<version>3.0.0-M1</version>
				<executions>
					<execution>
						<id>Add-2-local-repository</id>
						<phase>package</phase>
						<configuration>
							<packaging>jar</packaging>
							<!-- <file>${project.build.directory}\${project.artifactId}-jar-with-dependencies.jar</file> -->
							<!-- <file>${project.build.directory}\${project.artifactId}-${project.version}.jar</file> -->
							<file>${project.build.directory}\${project.artifactId}.jar</file>
						</configuration>
						<goals>
							<goal>install-file</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</project>

That’s all about how to create or build both war and jar files in web applications.

Source Code

Download

4 Thoughts to “Create Both war and jar Files using Maven”

  1. Alex

    Dan, you need to run next maven command “mvn clean compile package” to avoid this error.

  2. Dan

    giving error
    The specified file ‘ not exists

  3. test

    A tip from “test” – When developing in Eclipse, in the maven-jar-plugin, the “compile” phase line caused an annoying syntax error (it’s a issue with the Eclipse maven plugin apparently).
    I got around it by changing the maven-jar-plugin phase to “prepare-package” (I also changed the maven-install-plugin phase to “install” – seems more logical to me)

  4. test

    Brilliant solution – thank you. Very well explained too.

Leave a Comment