java - 如何从命令行运行Java项目(在Eclipse,Gradle中工作正常)

标签 java eclipse gradle

我有一个简单的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项目的某个地方,您会找到一个名为.jarlog4j.jarorg.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选项被忽略
因此,下一步:

  • 我不知道gradle是否正确输入了Class-Path条目。最好的选择是使用jarzip工具解压您的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文件。
  • 有一个“striper插件”,可以将所有各种jar混合在一个巨型jar中。这通常是个坏主意(它会使jar本身变得笨拙,并使构建花费更长的时间。如果要将Java代码部署到服务器,则可以自己管理Class-Path条目,并且如果要创建台式机,应用程序,您需要一个安装程序...可以同时管理类路径的东西。(实际上没有理由使用剥离器)。我建议不要使用这些。
  • 而是直接使用java -cp yourapp.jar:dep1.jar:dep2.jar com.foo.fullyqualified.ClassName运行。
  • 关于java - 如何从命令行运行Java项目(在Eclipse,Gradle中工作正常),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62979897/

    相关文章:

    java - MQTT主题匹配评估

    java - 格式化字符串内容 xtext 2.14

    java - Selenium 在java中的while循环中查找元素

    grails - 意外锁定协议(protocol) : Expected 3, 发现 49

    java - 为什么即使我不调用 get() 或 join() 这个 CompletableFuture 也能工作?

    java - Java 中的 Scanner 会阻止文件输入吗?

    java - 当我能够使用 setter 方法更改属性值时,封装有什么用?

    java - Ant 编译但不运行或创建 jar

    gradle - 在 gradle 任务中将提交从一个分支添加到另一个分支

    java - 在Spring Boot应用程序上继续收到白标错误吗?