我有一个小项目,在我的本地IDE中运行得很好,屏幕截图将显示项目结构:
我突出显示了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的任何提示?
答案 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的类加载器。