sav_
sav_

Reputation: 1

How to add classpath to maven

I want to create an executable jar with dependencies that are going to be outside the archive in folder lib. I found out that i can ask maven to copy dependencies into the folder and modify manifest file in my executable to know where to look for needed classes. The problem is that it does not add any classpaths to my manifest. Pom:

<?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>org.sav</groupId>
    <artifactId>console-app-01</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <project.build.sourceEncoding>utf-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>utf-8</project.reporting.outputEncoding>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.8</version>
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>
                                ${project.build.directory}/lib
                            </outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.4</version>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>lib/</classpathPrefix>
                            <mainClass>org.sav.app.App</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>com.kenai.nbpwr</groupId>
            <artifactId>joda-time</artifactId>
            <version>1.6.2-201110292322</version>
        </dependency>
    </dependencies>

</project>

After running mvn install my manifest looks like this:

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven 3.8.3
Built-By: abigo
Build-Jdk: 11.0.12
Main-Class: org.sav.app.App

But it won't run. It tells me that it cannot find needed classes. As soon as i add class-path manually it runs with no problems

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven 3.8.3
Built-By: abigo
Build-Jdk: 11.0.12
Main-Class: org.sav.app.App
Class-Path: lib/joda-time-1.6.2.jar lib/joda-time-1.6.2-201110292322.jar

Application:

package org.sav.app;

import org.joda.time.LocalTime;

public class App {

    public static void main(String[] args) {
        LocalTime currentTime = new LocalTime();
        System.out.printf("Current time is: %s%n", currentTime);
    }

}

Upvotes: 0

Views: 4727

Answers (3)

Adrian B.
Adrian B.

Reputation: 1570

To avoid that other people waste as much time as I did... I had a similar problem, where the jar that was built with openjdk 11 (worked fine with 8) and was included in a Docker image. The resulting image had the above issue with the embeded jar (outputting ClassNotFoundException for classes in jars that should have been on the classpath). The solution included two steps:

  • maven-jar-plugin version that worked 3.2.2 (I was using 3.2.0 before) [1]
  • dockerfile-maven-plugin explicitly set to execute on verify phase [2]. The reason behind this was that the image was being built before the jar manifest was updated somehow....

After these 2 changes, the resulting image had a jar with the correct manifest in it, that included the jars in the lib folder.

Code snippets:

[1]

<plugin>
   <artifactId>maven-jar-plugin</artifactId>
   <groupId>org.apache.maven.plugins</groupId>
   <version>3.2.2</version>
   <configuration>
      <archive>
         <manifest>
            <addClasspath>true</addClasspath>
            <classpathPrefix>lib/</classpathPrefix>
            <mainClass>someclass</mainClass>
         </manifest>
      </archive>
   </configuration>
</plugin>

[2]

<plugin>
   <groupId>com.spotify</groupId>
   <artifactId>dockerfile-maven-plugin</artifactId>
   <executions>
      <execution>
         <id>default</id>
         <phase>verify</phase>
         <goals>
            <goal>build</goal>
            <goal>push</goal>
         </goals>
      </execution>
   </executions>
   <configuration>
      ...
   </configuration>
</plugin>

Upvotes: 2

I'n in the same trouble now, and I can't find other workaround than downgrading maven version. I'm using maven 3.8.3, and I will download 3.6

Upvotes: 0

sav_
sav_

Reputation: 1

Used older version of maven and it all worked fine.

Upvotes: -3

Related Questions