简体   繁体   中英

NoClassDefFoundError in maven project with local dependency

I'm trying to run.jar file created by maven with one local dependency (processing library) that is not being recognized. I used maven-install-plugin. Library's jar is located in root/lib. After running

$ mvn validate
$ mvn clean package
$ java -cp target/my-app-1.0.jar com.mycompany.app.App

I get error:

Error: Could not find or load main class com.mycompany.app.App
Caused by: java.lang.NoClassDefFoundError: processing/core/PApplet

However the app works fine when I run:

$ java -cp target/classes:$HOME/.m2/repository/org/processing/core/10/core-10.jar com.mycompany.app.App

Here is my pom.xml:

<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>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <version>1.0</version>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>14</maven.compiler.source>
    <maven.compiler.target>14</maven.compiler.target>
  </properties>

  <dependencies>
    <!--  LOCAL  -->
    <dependency>
      <groupId>org.processing</groupId>
      <artifactId>core</artifactId>
      <version>10</version>
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-install-plugin</artifactId>
        <version>2.5.1</version>
        <configuration>
          <groupId>org.processing</groupId>
          <artifactId>core</artifactId>
          <version>10</version>
          <packaging>jar</packaging>
          <file>${pom.basedir}/lib/processing-core.jar</file>
          <generatePom>true</generatePom>
        </configuration>
        <executions>
          <execution>
            <id>install-jar-lib</id>
            <goals>
              <goal>install-file</goal>
            </goals>
            <phase>validate</phase>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  
</project>

And here is source:

package com.mycompany.app;

import processing.core.PApplet;

public class App extends PApplet{
    public static void main( String[] args ) {
        PApplet.main(App.class, args);
        System.out.println( "Hello World!" );
    }
}

My environment:

$ mvn -version
Apache Maven 3.6.3
Maven home: /usr/share/maven
Java version: 14.0.2, vendor: Private Build, runtime: /usr/lib/jvm/java-14-openjdk-amd64
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "5.8.0-33-generic", arch: "amd64", family: "unix"

Thank you for all suggestions.

The maven-install-plugin is used to install an artifact in your local maven repository. This is not what you want to do here. Your goal is to get a dependency in the classpath.

To be able to start your code with this command

java -cp target/my-app-1.0.jar com.mycompany.app.App

you have to ensure two things

  1. The application jar's manifest must contain the path of the dependency jar
  2. The dependency jar has to be at the specified location

For the first part, you can use the maven-jar-plugin :

<plugin>
    <artifactId>maven-jar-plugin</artifactId>
    <version>3.2.0</version>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <classpathPrefix>lib/</classpathPrefix>
            </manifest>
        </archive>
    </configuration>
</plugin>

Be aware that this will add all dependencies to the classpath, which might or might not be what you want.

For the second part, you can use the maven-dependency-plugin . This will copy all dependencies (or with appropriate configuration only selected dependencies) to target/lib

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

With this configuration, the target directory should look somewhat like this, showing only relevant files/directories:

target
|- lib
|  |- core-10.jar
|- my-app-1.0.jar

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM