错误的类路径声明获取java.lang.NoClassDefFoundError

时间:2018-03-14 13:28:52

标签: java classpath

我有一个小项目,在我的本地IDE中运行得很好,屏幕截图将显示项目结构:
enter image description here

我突出显示了jewelcli jar,因为在该类中我得到了标题中提到的异常。 在本地运行一切顺利,在测试ubuntu服务器上我得到:
java -verbose -classpath "/correct/path/jarName.jar:lib/jars/*" correct.package.and.main.Class ***all bootstrapping class from RT.JAR*** java.lang.NoClassDefFoundError: uk/co/flamingpenguin/jewel/cli/ArgumentValidationException at correct.package.and.main.Class.main(Class.java:31) Caused by: java.lang.ClassNotFoundException: uk.co.flamingpenguin.jewel.cli.ArgumentValidationException at java.net.URLClassLoader$1.run(URLClassLoader.java:366) at java.net.URLClassLoader$1.run(URLClassLoader.java:355) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:354) at java.lang.ClassLoader.loadClass(ClassLoader.java:423) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:356) ... 1 more
我不认为这实际上与jewelcli jar特别相关,因为我仔细检查了它的位置: unzip -l jarname.jar | grep jewelcli 435937 11-20-11 01:22 lib/jars/jewelcli-0.7.6.jar

但它发生在那个Jar上,因为它是程序需要的第一个jar(在rt.jar中的所有引导类之后)。
This是我基于命令行的地方 但我也看到了:
Subdirectories are not searched recursively. For example, foo/* looks for JAR files only in foo, not in foo/bar, foo/baz, etc.
我认为通过在命令行中指定包含所有库的jar文件,java会自动地,并且递归地扫描所有子目录,但它不起作用:
java -verbose -classpath "/correct/path/jarName" correct.package.and.main.Class

关于如何让java扫描我在-classpath选项中指定的整个jar的任何提示?

1 个答案:

答案 0 :(得分:0)

  

我认为通过在命令行中指定包含所有库的jar文件,java会自动地,并递归地扫描所有子目录

这取决于。标准Java类加载器不知道如何从嵌入其他JAR的JAR中加载类。

这就是你似乎所做的......如果我正确地读你的问题。

有几种方法可以解决这个问题:

  • 将所有依赖JAR复制到服务器,将它们放入目录,然后将目录添加到类路径中; e.g。

    java -classpath "/correct/path/jarName.jar:/correct/path/lib/*"  \
             correct.package.and.main.Class
    
  • 通过将依赖JAR解压缩到目录中,添加类并从树中生成JAR来构建UberJAR或着色JAR。有用于构建此类JAR文件的maven插件。

  • 使用像Spring Boot这样的东西,它使用一个能够理解如何使用JAR处理JAR的类加载器。