Set Up The Classpath
Contents
Add A Class-Path Entry To The Manifest
[Top]
Maven Archiver can add the classpath of your project to the manifest. This is done with the <addClasspath>
configuration element.
- <project>
- ...
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- ...
- <configuration>
- <archive>
- <manifest>
- <addClasspath>true</addClasspath>
- </manifest>
- </archive>
- </configuration>
- ...
- </plugin>
- </plugins>
- </build>
- ...
- <dependencies>
- <dependency>
- <groupId>commons-lang</groupId>
- <artifactId>commons-lang</artifactId>
- <version>2.1</version>
- </dependency>
- <dependency>
- <groupId>org.codehaus.plexus</groupId>
- <artifactId>plexus-utils</artifactId>
- <version>1.1</version>
- </dependency>
- </dependencies>
- ...
- </project>
The manifest produced using the above configuration would look like this:
- Manifest-Version: 1.0
- Created-By: Apache Maven ${maven.version}
- Build-Jdk: ${java.version}
- Class-Path: plexus-utils-1.1.jar commons-lang-2.1.jar
Make The Jar Executable
[Top]
If you want to create an executable jar file, you need to configure Maven Archiver accordingly. You need to tell it which main class to use. This is done with the <mainClass>
configuration element. Here is a sample pom.xml
configured to add the classpath and use the class fully.qualified.MainClass
as the main class:
- <project>
- ...
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- ...
- <configuration>
- <archive>
- <manifest>
- <addClasspath>true</addClasspath>
- <mainClass>fully.qualified.MainClass</mainClass>
- </manifest>
- </archive>
- </configuration>
- ...
- </plugin>
- </plugins>
- </build>
- ...
- <dependencies>
- <dependency>
- <groupId>commons-lang</groupId>
- <artifactId>commons-lang</artifactId>
- <version>2.1</version>
- </dependency>
- <dependency>
- <groupId>org.codehaus.plexus</groupId>
- <artifactId>plexus-utils</artifactId>
- <version>1.1</version>
- </dependency>
- </dependencies>
- ...
- </project>
The manifest produced using the above configuration would look like this:
- Manifest-Version: 1.0
- Created-By: Apache Maven ${maven.version}
- Build-Jdk: ${java.version}
- Main-Class: fully.qualified.MainClass
- Class-Path: plexus-utils-1.1.jar commons-lang-2.1.jar
Altering The Classpath: Defining a Classpath Directory Prefix
[Top]
Sometimes it is useful to be able to alter the classpath, for example when creating skinny war-files. This can be achieved with the <classpathPrefix>
configuration element.
- <project>
- ...
- <build>
- <plugins>
- <plugin>
- <artifactId>maven-war-plugin</artifactId>
- <configuration>
- <archive>
- <manifest>
- <addClasspath>true</addClasspath>
- <classpathPrefix>lib/</classpathPrefix>
- </manifest>
- </archive>
- </configuration>
- </plugin>
- </plugins>
- </build>
- ...
- <dependencies>
- <dependency>
- <groupId>commons-lang</groupId>
- <artifactId>commons-lang</artifactId>
- <version>2.1</version>
- </dependency>
- <dependency>
- <groupId>org.codehaus.plexus</groupId>
- <artifactId>plexus-utils</artifactId>
- <version>1.1</version>
- </dependency>
- </dependencies>
- ...
- </project>
The manifest classpath produced using the above configuration would look like this:
- Class-Path: lib/plexus-utils-1.1.jar lib/commons-lang-2.1.jar
Altering The Classpath: Using a Maven Repository-Style Classpath
[Top]
(Since: 2.3, see below)
Occasionally, you may want to include a Maven repository-style directory structure in your archive. If you wish to reference the dependency archives within those directories in your manifest classpath, try using the <classpathLayoutType>
element with a value of 'repository'
, like this:
- <project>
- ...
- <build>
- <plugins>
- <plugin>
- <artifactId>maven-jar-plugin</artifactId>
- <version>2.3</version>
- <configuration>
- <archive>
- <manifest>
- <addClasspath>true</addClasspath>
- <classpathPrefix>lib/</classpathPrefix>
- <classpathLayoutType>repository</classpathLayoutType>
- </manifest>
- </archive>
- </configuration>
- </plugin>
- </plugins>
- </build>
- ...
- <dependencies>
- <dependency>
- <groupId>commons-lang</groupId>
- <artifactId>commons-lang</artifactId>
- <version>2.1</version>
- </dependency>
- <dependency>
- <groupId>org.codehaus.plexus</groupId>
- <artifactId>plexus-utils</artifactId>
- <version>1.1</version>
- </dependency>
- </dependencies>
- ...
- </project>
The manifest classpath produced using the above configuration would look like this:
- Class-Path: lib/org/codehaus/plexus/plexus-utils/1.1/plexus-utils-1.1.jar lib/commons-lang/commons-lang/2.1/commons-lang-2.1.jar
Altering The Classpath: Using a Custom Classpath Format
[Top]
(Since: 2.4)
At times, you may have dependency archives in a custom format within your own archive, one that doesn't conform to any of the above classpath layouts. If you wish to define a custom layout for dependency archives within your archive's manifest classpath, try using the <classpathLayoutType>
element with a value of 'custom'
, along with the <customClasspathLayout>
element, like this:
- <project>
- ...
- <build>
- <plugins>
- <plugin>
- <artifactId>maven-war-plugin</artifactId>
- <configuration>
- <archive>
- <manifest>
- <addClasspath>true</addClasspath>
- <classpathLayoutType>custom</classpathLayoutType>
- <customClasspathLayout>WEB-INF/lib/$${artifact.groupIdPath}/$${artifact.artifactId}-$${artifact.version}$${dashClassifier?}.$${artifact.extension}</customClasspathLayout>
- </manifest>
- </archive>
- </configuration>
- </plugin>
- </plugins>
- </build>
- ...
- <dependencies>
- <dependency>
- <groupId>commons-lang</groupId>
- <artifactId>commons-lang</artifactId>
- <version>2.1</version>
- </dependency>
- <dependency>
- <groupId>org.codehaus.plexus</groupId>
- <artifactId>plexus-utils</artifactId>
- <version>1.1</version>
- </dependency>
- </dependencies>
- ...
- </project>
This classpath layout is a little more involved than the previous examples. To understand how the value of the <customClasspathLayout>
configuration is interpreted, it's useful to understand the rules applied when resolving expressions within the value:
- If present, trim off the prefix 'artifact.' from the expression.
- Attempt to resolve the expression as a reference to the Artifact using reflection (eg.
'artifactId'
becomes a reference to the method'getArtifactId()'
). - Attempt to resolve the expression as a reference to the ArtifactHandler of the current Artifact, again using reflection (eg.
'extension'
becomes a reference to the method'getExtension()'
). - Attempt to resolve the expression as a key in the special-case Properties instance, which contains the following mappings:
'dashClassifier'
: If the Artifact has a classifier, this will be'-$artifact.classifier'
, otherwise this is an empty string.'dashClassifier?'
: This is a synonym of'dashClassifier'
.'groupIdPath'
: This is the equivalent of'$artifact.groupId'
, with all'.'
characters replaced by'/'
.
The manifest classpath produced using the above configuration would look like this:
- Class-Path: WEB-INF/lib/org/codehaus/plexus/plexus-utils-1.1.jar WEB-INF/lib/commons-lang/commons-lang-2.1.jar
Handling Snapshot Versions
[Top]
(Since 2.4)
Depending on how you construct your archive, you may have the ability to specify whether snapshot dependency archives are included with the version suffix '-SNAPSHOT'
, or whether the unique timestamp and build-number for that archive is used. For instance, the Assembly Plugin allows you to make this decision in the <outputFileNameMapping>
element of its <dependencySet
> descriptor section.
Forcing the use of -SNAPSHOT versions when using the simple (default) or repository classpath layout
To force the use of '-SNAPSHOT'
version naming, simply disable the <useUniqueVersions>
configuration element, like this:
- <useUniqueVersions>false</useUniqueVersions>
Forcing the use of -SNAPSHOT versions with custom layouts
To force the use of '-SNAPSHOT'
version naming, simply replace '$artifact.version'
with '$artifact.baseVersion'
in the custom layout example above, so it looks like this:
- <customClasspathLayout>WEB-INF/lib/${artifact.groupIdPath}/${artifact.artifactId}-${artifact.baseVersion}${dashClassifier?}.${artifact.extension}</customClasspathLayout>
The full example configuration would look like this:
- <project>
- ...
- <build>
- <plugins>
- <plugin>
- <artifactId>maven-war-plugin</artifactId>
- <configuration>
- <archive>
- <manifest>
- <addClasspath>true</addClasspath>
- <classpathLayoutType>custom</classpathLayoutType>
- <customClasspathLayout>WEB-INF/lib/${artifact.groupIdPath}/${artifact.artifactId}-${artifact.version}${dashClassifier?}.${artifact.extension}</customClasspathLayout>
- </manifest>
- </archive>
- </configuration>
- </plugin>
- </plugins>
- </build>
- ...
- </project>