简体   繁体   English

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

[英]Wrong classpath declaration gets a java.lang.NoClassDefFoundError

I have a small project which in my local IDE is running just fine, a screenshot will show the project structure: 我有一个小项目,在我的本地IDE中运行得很好,屏幕截图将显示项目结构:
在此处输入图片说明

I have highlighted the jewelcli jar because on that class i get the exception mentioned in the header. 我突出显示了jewelcli jar,因为在该类上,我收到了标题中提到的异常。 While running locally all goes fine, on a testing ubuntu server i get: 在本地运行时,一切正常,在测试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
I dont think this is actually related at all to that jewelcli jar in particular, because i double checked and its there: unzip -l jarname.jar | grep jewelcli 435937 11-20-11 01:22 lib/jars/jewelcli-0.7.6.jar 我认为这实际上与那个jewelcli jar根本没有任何关系,因为我仔细检查了其中的内容: unzip -l jarname.jar | grep jewelcli 435937 11-20-11 01:22 lib/jars/jewelcli-0.7.6.jar unzip -l jarname.jar | grep jewelcli 435937 11-20-11 01:22 lib/jars/jewelcli-0.7.6.jar

But it happens for that Jar because it is the very first jar that the program needs (after all the bootstrapping classes in rt.jar). 但是它发生在那个Jar上,因为它是程序需要的第一个jar(在rt.jar中的所有引导类之后)。
This is where i am basing my command line from But i also see: 是我基于命令行的地方,但我也看到:
Subdirectories are not searched recursively. For example, foo/* looks for JAR files only in foo, not in foo/bar, foo/baz, etc.
I thought that by specifying in the command line the jar file containing all the libraries, java would automaticaly, and recursively, scan all subdirectories, but it does not work: 我认为,通过在命令行中指定包含所有库的jar文件,java会自动并递归地扫描所有子目录,但是它不起作用:
java -verbose -classpath "/correct/path/jarName" correct.package.and.main.Class

Any tip on how can i get java to scan the whole jar i specify in the -classpath option? 关于如何获取Java来扫描我在-classpath选项中指定的整个jar的任何提示?

I thought that by specifying in the command line the jar file containing all the libraries, java would automaticaly, and recursively, scan all subdirectories 我认为通过在命令行中指定包含所有库的jar文件,java会自动并递归地扫描所有子目录

It depends. 这取决于。 The standard Java classloaders do not know how to load classes from JARs that embedded inside other JARs. 标准Java类加载器不知道如何从嵌入在其他JAR中的JAR加载类。

And that's what you appear to have done ... if I am reading your question correctly. 这就是您似乎已完成的工作……如果我正确阅读了您的问题。

There are a few ways to address this: 有几种解决方法:

  • Copy all of the dependent JARs to the server, put them into a directory, and add the directory to the classpath; 将所有依赖的JAR复制到服务器,将它们放入目录,然后将目录添加到类路径; eg 例如

     java -classpath "/correct/path/jarName.jar:/correct/path/lib/*" \\ correct.package.and.main.Class 
  • Build an UberJAR or shaded JAR by unpacking the dependent JARs into a directory, adding your classes and producing a JAR from the tree. 通过将依赖的JAR解压缩到目录中,添加类并从树中生成JAR,来构建UberJAR或带阴影的JAR。 There are maven plugins for building such JAR files. 有用于构建此类JAR文件的Maven插件。

  • Use something like Spring Boot which uses a classloader that understands how to deal with JARs withing JARs. 使用类似Spring Boot之类的东西,它使用一个类加载器,该类加载器了解如何使用JAR处理JAR。

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

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