简体   繁体   中英

How to fix NoClassDefFoundError for external JAR's Classes?

I added own external jar to my main project's pom. It is;

    <dependency>
        <groupId>com.company</groupId>
        <artifactId>antlr-plsql</artifactId>
        <scope>system</scope>
        <version>1.0</version>
        <systemPath>${project.basedir}\lib\antlr-plsql-1.0.0.jar</systemPath>
    </dependency>

The project is working when I run on eclipse. But when I get jar with maven (params: clean install -DskipTests). I got an error;

java.lang.NoClassDefFoundError: company/antlr/core/SimplePlsqlListener
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:468)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:92)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)

This Class comes from my external jar. What is the problem about external jar?

The NoClassDefFoundError is caused when you jar is unable to locate the dependency jars in the classpath. By default, Maven doesn't bundle dependencies in the JAR file when it builds the output jar, for the same reason you will need to provide them on the classpath when you're trying to execute your JAR file from the command-line.

This is the reason JVM can't find the library class files when trying to execute your code.

You could manually specify the libraries on the classpath with the -cp parameter, but that quickly becomes tiresome.

A better solution is to "shade" (include) the library code into your output JAR file. There is a Maven plugin called the maven-shade-plugin to do this. You need to register it in your POM, and it will automatically build an "uber-JAR" also called as FAT jar containing your classes and the classes for your library code as well when you run mvn package command.

To simply bundle all required libraries, add the following to your POM:

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>3.2.4</version>
        <configuration>
          <!-- put your configurations here -->
        </configuration>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  ...
</project>

Once this is done, you can rerun the commands you used above:

$ mvn package

You can find more details regarding maven-shade-plugin here .

Also instead of directly referring to the external jar from its location, you can rather let maven handle it for you. Maven lets you install third-party jars using mvn install:install-file

To install a JAR in the local repository use the following command:

mvn install:install-file -Dfile=<path-to-file> -DgroupId=<group-id> -DartifactId=<artifact-id> -Dversion=<version> -Dpackaging=<packaging>

If there's a pom-file as well, you can install it with the following command:

mvn install:install-file -Dfile=<path-to-file> -DpomFile=<path-to-pomfile>

With version 2.5 of the maven-install-plugin, it can get even simpler: if the JAR was built by Apache Maven, it'll contain a pom.xml in a subfolder of the META-INF/ directory, which will be read by default. In that case, all you need to do is:

mvn org.apache.maven.plugins:maven-install-plugin:2.5.2:install-file -Dfile=<path-to-file>

This works for me; Firstly run this command:

mvn org.apache.maven.plugins:maven-install-plugin:2.5.2:install-file -Dfile=<path-to-file>

After that, change pom.xml dependency to:

    <dependency>
        <groupId>com.company</groupId>
        <artifactId>antlr-plsql</artifactId>
        <scope>compile</scope>
        <version>1.0</version>
    </dependency>

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