Building Other Types of Projects
The lifecycle is applicable to any project type. For instance, let’s create a simple web application in the base directory:
mvn archetype:generate \
-DarchetypeGroupId=org.apache.maven.archetypes \
-DarchetypeArtifactId=maven-archetype-webapp \
-DgroupId=com.mycompany.app \
-DartifactId=my-webapp
Note that these must be all in one line. This will create a directory named my-webapp
, containing the following project descriptor:
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-webapp</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>my-webapp</finalName>
</build>
</project>
Notice the <packaging>
element—it tells Maven to build as a WAR. Navigate into the webapp project directory and try the command:
mvn package
You’ll see target/my-webapp.war
has been built, and all the normal steps have been executed.
Building Multiple Projects Simultaneously
Maven has built-in support for dealing with multiple modules. In this section, we’ll demonstrate how to build both the WAR mentioned above and include the previous JAR in one go.
First, we need to add a parent pom.xml
file above the other two modules in the directory, so it should look like this:
+- pom.xml
+- my-app
| +- pom.xml
| +- src
| +- main
| +- java
+- my-webapp
| +- pom.xml
| +- src
| +- main
| +- webapp
The created POM file should contain the following:
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>app</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>my-app</module>
<module>my-webapp</module>
</modules>
</project>
We need the dependency on the JAR in the web app, so add it to my-webapp/pom.xml
:
...
<dependencies>
<dependency>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
...
</dependencies>
Finally, in the other two pom.xml
files in the subdirectories, add the following <parent>
element:
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.mycompany.app</groupId>
<artifactId>app</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
...
Now, execute the command from the parent directory:
mvn verify
You now have the WAR created in my-webapp/target/my-webapp.war
, including the JAR:
$ jar tvf my-webapp/target/my-webapp-1.0-SNAPSHOT.war
0 Fri Jun 24 10:59:56 EST 2005 META-INF/
222 Fri Jun 24 10:59:54 EST 2005 META-INF/MANIFEST.MF
0 Fri Jun 24 10:59:56 EST 2005 META-INF/maven/
0 Fri Jun 24 10:59:56 EST 2005 META-INF/maven/com.mycompany.app/
0 Fri Jun 24 10:59:56 EST 2005 META-INF/maven/com.mycompany.app/my-webapp/
3239 Fri Jun 24 10:59:56 EST 2005 META-INF/maven/com.mycompany.app/my-webapp/pom.xml
0 Fri Jun 24 10:59:56 EST 2005 WEB-INF/
215 Fri Jun 24 10:59:56 EST 2005 WEB-INF/web.xml
123 Fri Jun 24 10:59:56 EST 2005 META-INF/maven/com.mycompany.app/my-webapp/pom.properties
52 Fri Jun 24 10:59:56 EST 2005 index.jsp
0 Fri Jun 24 10:59:56 EST 2005 WEB-INF/lib/
2713 Fri Jun 24 10:59:56 EST 2005 WEB-INF/lib/my-app-1.0-SNAPSHOT.jar
How does this work? First, the created parent POM (named app
) defines the pom
packaging and the list of modules. This tells Maven to operate on all projects in the project set, not just the current one (to override this behavior, you can use the --non-recursive
command-line option).
Next, we tell the WAR that it needs the my-app
JAR. This is done for several reasons:
- To make any code in the WAR (there’s no code in this example) available on the classpath.
- To ensure the JAR is always compiled before the WAR.
- To instruct the WAR plugin to include the JAR in its lib directory.
You might have noticed that junit-4.11.jar
is a dependency but doesn’t end up in the WAR. This is because of the <scope>test</scope>
element—it’s only for elements needed for testing, so it’s not included in the web app like the compile-time dependency my-app
.
The final step is including the parent definition. This ensures that even if the projects are released separately from the parent project, the POM can still be found in the repository.