Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maven - how can I add an arbitrary classpath entry to a jar?

I have an unusual situation where I need to add an arbitrary classpath entry (that points to a jar file) into the manifest of an executable jar. (This is for a Swing desktop application.)

The maven-jar-plugin generates the "Class-Path" entry for the jar manifest using the maven dependencies, and there doesn't appear to be any way of adding arbitrary entries.

I also looked at hard-coding the arbitrary classpath entry into the batch file that starts the application, using the "-classpath" parameter, but I can't figure out how to get Maven to filter the classpath into a batch file.

like image 712
Ken Liu Avatar asked Oct 02 '09 14:10

Ken Liu


Video Answer


2 Answers

I found that there is an easy solution for this problem. You can add a <Class-Path> element to <manifestEntries> element, and set <addClassPath>true</addClassPath> to <manifest> element. So value of <Class-Path> element is added to class-path automatically. Example:

<plugin>   <groupId>org.apache.maven.plugins</groupId>   <artifactId>maven-jar-plugin</artifactId>   <configuration>     <archive>       <manifest>         <addDefaultImplementationEntries>true</addDefaultImplementationEntries>         <addClasspath>true</addClasspath>         <mainClass>your.main.Class</mainClass>       </manifest>       <manifestEntries>         <Class-Path>../conf/</Class-Path>       </manifestEntries>     </archive>   </configuration> </plugin> 
like image 192
Ali Reza Avatar answered Dec 06 '22 06:12

Ali Reza


Update: Here's how to filter a classpath into a custom manifest.

The maven-dependency-plugin's build-classpath goal can be configured to output the classpath to a file in the properties format (i.e. classpath=[classpath]). You then configure the filters element to use the generated classpath file, and configure the resources directory to be filtered.

For example:

<build>   <plugins>     <plugin>       <artifactId>maven-dependency-plugin</artifactId>       <version>2.1</version>       <executions>         <execution>           <phase>generate-resources</phase>           <goals>             <goal>build-classpath</goal>           </goals>         </execution>       </executions>       <configuration>         <outputFilterFile>true</outputFilterFile>         <outputFile>${project.build.directory}/classpath.properties</outputFile>       </configuration>     </plugin>     <plugin>       <artifactId>maven-jar-plugin</artifactId>       <configuration>         <archive>           <manifestFile>             ${project.build.outputDirectory}/META-INF/MANIFEST.MF           </manifestFile>         </archive>       </configuration>     </plugin>   </plugins>   <filters>     <filter>${project.build.directory}/classpath.properties</filter>   </filters>   <resources>     <resource>       <directory>src/main/resources</directory>       <filtering>true</filtering>     </resource>   </resources> </build> 

Then specify the following in src/main/resources/META-INF/Manifest.MF:

Bundle-Version: 4.0.0 ... Classpath: ${classpath};[specify additional entries here] 

Note: there is a bug with this processing using the standard window path separator (\), the generate path is stripped of separators (note it works fine on Linux). You can get the classpath to be generated correctly for Windows by specifying <fileSeparator>\\\\</fileSeparator> in the build-classpath goal's configuration.


You can customise the manifest in the jar-plugin's configuration. To do so you'd add something like this to your pom.

<plugin>   <groupId>org.apache.maven.plugins</groupId>   <artifactId>maven-jar-plugin</artifactId>   ...   <configuration>     <archive>       <index>true</index>       <manifest>         <addClasspath>true</addClasspath>       </manifest>       <manifestEntries>         <mode>development</mode>         <url>${pom.url}</url>         <key>value</key>       </manifestEntries>     </archive>   </configuration>   ... </plugin> 

The full archiver specification provides quite a few options. See the examples page for options on configuring the classpath.

If none of these work for you, you can define your own Manifest, set up properties containing the required entries and use a filter to populate the manifest with those properties

like image 41
Rich Seller Avatar answered Dec 06 '22 05:12

Rich Seller