我有一个简单的Java程序。我正在使用gradle在Eclipse中进行开发,并且正在使用log4j2进行日志记录。这一切都很好。
当我从命令行运行时,我会执行gradlew构建,但是运行jar时会出现错误:
java -jar build\libs\testproj.jar
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/logging/log4j/LogManager
at com.xxxxxx.practice.App.<clinit>(App.java:17)
Caused by: java.lang.ClassNotFoundException: org.apache.logging.log4j.LogManager
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:602)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
... 1 more
我可以在userprofile.gradle文件夹中看到一堆log4j文件,并且可以运行gradle dist任务,然后获取并解压缩生成的zip文件,然后指向该文件的内容,但是是否有避免这种情况的方法?当然,我可以添加一些东西到 list 中,或者可以让我随意从命令行运行而没有任何开销吗?需要明确的是,只有日志记录存在此问题。除了运行它之外,测试还可以从命令行进行,而日志从eclipse可以正常运行。
最佳答案
在eclipse项目的某个地方,您会找到一个名为.jar
或log4j.jar
或org.apache.logging-log4j.jar
的库(这些结尾在log4j-api.jar
中)或类似的内容。
该jar包含在命令行上运行时缺少的类。尝试一下:jar tvf log4j.jar
打印jar的内容,您会发现其中包含org/apache/logging/log4j/LogManager.class
。
在编译期间和在运行Java应用程序期间,此类必须位于classpath上。 Eclipse正在处理它的编译部分。
如果将Java作为java com.foo.ClassName
运行,则类路径由-cp
参数定义:java -cp testproj.jar:log4j.jar com.foo.yourapp.TestApp
将起作用(在Windows上使用分号)。如果未指定,则使用系统环境变量CLASSPATH
,但不要这样做(毕竟您可以在一台计算机上运行多个Java应用程序,因此全局设置没有任何意义)。
但是,如果使用java -jar myjar.jar
运行Java,则类路径仅取自jar文件本身; jar文件中有一个名为META-INF/MANIFEST.MF
的文件,它包含(以文本形式)键/值对。相关的是Class-Path: foo.jar bar.jar
条目:jar文件的空格分隔列表,相对于jar所在的目录。
使用-cp
选项时,不能使用-jar
选项; -cp
选项被忽略。
因此,下一步:
jar
或zip
工具解压您的jar,检查MANIFEST.MF文件并查看其中的内容。例如,如果该文件中存在Class-Path: lib/log4j.jar
,则确保如果testapp.jar位于/Users/Dev123456/project/testapp.jar
,则该log4j jar位于/Users/Dev123456/project/lib/log4j.jar
。如果没有类路径条目,则错误出在gradle配置中。在这种情况下,您将必须发布build.gradle文件。java -cp yourapp.jar:dep1.jar:dep2.jar com.foo.fullyqualified.ClassName
运行。关于java - 如何从命令行运行Java项目(在Eclipse,Gradle中工作正常),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62979897/