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.

  1. <project>
  2. ...
  3. <build>
  4. <plugins>
  5. <plugin>
  6. <groupId>org.apache.maven.plugins</groupId>
  7. <artifactId>maven-jar-plugin</artifactId>
  8. ...
  9. <configuration>
  10. <archive>
  11. <manifest>
  12. <addClasspath>true</addClasspath>
  13. </manifest>
  14. </archive>
  15. </configuration>
  16. ...
  17. </plugin>
  18. </plugins>
  19. </build>
  20. ...
  21. <dependencies>
  22. <dependency>
  23. <groupId>commons-lang</groupId>
  24. <artifactId>commons-lang</artifactId>
  25. <version>2.1</version>
  26. </dependency>
  27. <dependency>
  28. <groupId>org.codehaus.plexus</groupId>
  29. <artifactId>plexus-utils</artifactId>
  30. <version>1.1</version>
  31. </dependency>
  32. </dependencies>
  33. ...
  34. </project>

The manifest produced using the above configuration would look like this:

  1. Manifest-Version: 1.0
  2. Created-By: Apache Maven ${maven.version}
  3. Build-Jdk: ${java.version}
  4. 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:

  1. <project>
  2. ...
  3. <build>
  4. <plugins>
  5. <plugin>
  6. <groupId>org.apache.maven.plugins</groupId>
  7. <artifactId>maven-jar-plugin</artifactId>
  8. ...
  9. <configuration>
  10. <archive>
  11. <manifest>
  12. <addClasspath>true</addClasspath>
  13. <mainClass>fully.qualified.MainClass</mainClass>
  14. </manifest>
  15. </archive>
  16. </configuration>
  17. ...
  18. </plugin>
  19. </plugins>
  20. </build>
  21. ...
  22. <dependencies>
  23. <dependency>
  24. <groupId>commons-lang</groupId>
  25. <artifactId>commons-lang</artifactId>
  26. <version>2.1</version>
  27. </dependency>
  28. <dependency>
  29. <groupId>org.codehaus.plexus</groupId>
  30. <artifactId>plexus-utils</artifactId>
  31. <version>1.1</version>
  32. </dependency>
  33. </dependencies>
  34. ...
  35. </project>

The manifest produced using the above configuration would look like this:

  1. Manifest-Version: 1.0
  2. Created-By: Apache Maven ${maven.version}
  3. Build-Jdk: ${java.version}
  4. Main-Class: fully.qualified.MainClass
  5. 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.

  1. <project>
  2. ...
  3. <build>
  4. <plugins>
  5. <plugin>
  6. <artifactId>maven-war-plugin</artifactId>
  7. <configuration>
  8. <archive>
  9. <manifest>
  10. <addClasspath>true</addClasspath>
  11. <classpathPrefix>lib/</classpathPrefix>
  12. </manifest>
  13. </archive>
  14. </configuration>
  15. </plugin>
  16. </plugins>
  17. </build>
  18. ...
  19. <dependencies>
  20. <dependency>
  21. <groupId>commons-lang</groupId>
  22. <artifactId>commons-lang</artifactId>
  23. <version>2.1</version>
  24. </dependency>
  25. <dependency>
  26. <groupId>org.codehaus.plexus</groupId>
  27. <artifactId>plexus-utils</artifactId>
  28. <version>1.1</version>
  29. </dependency>
  30. </dependencies>
  31. ...
  32. </project>

The manifest classpath produced using the above configuration would look like this:

  1. 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:

  1. <project>
  2. ...
  3. <build>
  4. <plugins>
  5. <plugin>
  6. <artifactId>maven-jar-plugin</artifactId>
  7. <version>2.3</version>
  8. <configuration>
  9. <archive>
  10. <manifest>
  11. <addClasspath>true</addClasspath>
  12. <classpathPrefix>lib/</classpathPrefix>
  13. <classpathLayoutType>repository</classpathLayoutType>
  14. </manifest>
  15. </archive>
  16. </configuration>
  17. </plugin>
  18. </plugins>
  19. </build>
  20. ...
  21. <dependencies>
  22. <dependency>
  23. <groupId>commons-lang</groupId>
  24. <artifactId>commons-lang</artifactId>
  25. <version>2.1</version>
  26. </dependency>
  27. <dependency>
  28. <groupId>org.codehaus.plexus</groupId>
  29. <artifactId>plexus-utils</artifactId>
  30. <version>1.1</version>
  31. </dependency>
  32. </dependencies>
  33. ...
  34. </project>

The manifest classpath produced using the above configuration would look like this:

  1. 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:

  1. <project>
  2. ...
  3. <build>
  4. <plugins>
  5. <plugin>
  6. <artifactId>maven-war-plugin</artifactId>
  7. <configuration>
  8. <archive>
  9. <manifest>
  10. <addClasspath>true</addClasspath>
  11. <classpathLayoutType>custom</classpathLayoutType>
  12. <customClasspathLayout>WEB-INF/lib/$${artifact.groupIdPath}/$${artifact.artifactId}-$${artifact.version}$${dashClassifier?}.$${artifact.extension}</customClasspathLayout>
  13. </manifest>
  14. </archive>
  15. </configuration>
  16. </plugin>
  17. </plugins>
  18. </build>
  19. ...
  20. <dependencies>
  21. <dependency>
  22. <groupId>commons-lang</groupId>
  23. <artifactId>commons-lang</artifactId>
  24. <version>2.1</version>
  25. </dependency>
  26. <dependency>
  27. <groupId>org.codehaus.plexus</groupId>
  28. <artifactId>plexus-utils</artifactId>
  29. <version>1.1</version>
  30. </dependency>
  31. </dependencies>
  32. ...
  33. </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:

  1. If present, trim off the prefix 'artifact.' from the expression.
  2. Attempt to resolve the expression as a reference to the Artifact using reflection (eg. 'artifactId' becomes a reference to the method 'getArtifactId()').
  3. 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()').
  4. 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:

  1. 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:

  1. <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:

  1. <customClasspathLayout>WEB-INF/lib/${artifact.groupIdPath}/${artifact.artifactId}-${artifact.baseVersion}${dashClassifier?}.${artifact.extension}</customClasspathLayout>

The full example configuration would look like this:

  1. <project>
  2. ...
  3. <build>
  4. <plugins>
  5. <plugin>
  6. <artifactId>maven-war-plugin</artifactId>
  7. <configuration>
  8. <archive>
  9. <manifest>
  10. <addClasspath>true</addClasspath>
  11. <classpathLayoutType>custom</classpathLayoutType>
  12. <customClasspathLayout>WEB-INF/lib/${artifact.groupIdPath}/${artifact.artifactId}-${artifact.version}${dashClassifier?}.${artifact.extension}</customClasspathLayout>
  13. </manifest>
  14. </archive>
  15. </configuration>
  16. </plugin>
  17. </plugins>
  18. </build>
  19. ...
  20. </project>