简体   繁体   English

如何修复外部 JAR 类的 NoClassDefFoundError?

[英]How to fix NoClassDefFoundError for external JAR's Classes?

I added own external jar to my main project's pom.我在主项目的 pom.xml 中添加了自己的外部 jar。 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.当我在 eclipse 上运行时,该项目正在运行。 But when I get jar with maven (params: clean install -DskipTests).但是当我得到 jar 和 maven (参数:全新安装 -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.这个 Class 来自我的外部 jar。 What is the problem about external jar?外接 jar 有什么问题?

The NoClassDefFoundError is caused when you jar is unable to locate the dependency jars in the classpath.当您 jar 无法在类路径中找到依赖项 jars 时,会导致 NoClassDefFoundError。 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. 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.这就是 JVM 在尝试执行代码时找不到库 class 文件的原因。

You could manually specify the libraries on the classpath with the -cp parameter, but that quickly becomes tiresome.您可以使用 -cp 参数手动指定类路径上的库,但这很快就会变得令人厌烦。

A better solution is to "shade" (include) the library code into your output JAR file.更好的解决方案是将库代码“隐藏”(包含)到您的 output JAR 文件中。 There is a Maven plugin called the maven-shade-plugin to do this.有一个名为maven-shade-plugin的 Maven 插件可以执行此操作。 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.您需要在 POM 中注册它,当您运行mvn package命令时,它会自动构建一个“uber-JAR”,也称为 FAT jar,其中包含您的类和库代码的类。

To simply bundle all required libraries, add the following to your POM:要简单地捆绑所有必需的库,请将以下内容添加到您的 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 .您可以 在此处找到有关 maven-shade-plugin 的更多详细信息。

Also instead of directly referring to the external jar from its location, you can rather let maven handle it for you.此外,与其直接从其位置引用外部 jar,不如让 maven 为您处理。 Maven lets you install third-party jars using mvn install:install-file Maven 允许您使用mvn install:install-file第三方 jars

To install a JAR in the local repository use the following command:要在本地存储库中安装 JAR,请使用以下命令:

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:如果还有 pom 文件,您可以使用以下命令安装它:

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. 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默认。 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:之后,将 pom.xml 依赖项更改为:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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