带有log4j的java.lang.ClassNotFoundException

时间:2015-11-05 22:10:32

标签: java linux jar classloader

我正在用gradle尝试我的第一个项目。我的项目与log4j-1.2.17.jar有依赖关系。构建项目后,会生成一个jar文件。我尝试使用以下命令运行:

java -classpath ".:/home/ec2-user/dlsvr/lib/log4j-1.2.17.jar" -jar dlsvr.jar

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/log4j/Logger
        at com.secutrans.dlsvr.DLSvrMain.<clinit>(DLSvrMain.java:27)
Caused by: java.lang.ClassNotFoundException: org.apache.log4j.Logger
        at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        ... 1 more

但是如果我用gradle构建一个fatjar,那么fatjar可以在不指定任何类路径的情况下工作。 gradle中的依赖语句如下:

dependencies 
{
    compile files("/home/ec2-user/dlsvr/lib/log4j-1.2.17.jar")
}

2 个答案:

答案 0 :(得分:0)

您忘记在类路径中包含log4j.jar

参考: Does java -jar option alter classpath options

An executable JAR must reference all the other dependent JARs it requires through the Class-Path header of the manifest file. The environment variable CLASSPATH and any class path specified on the command line is ignored by the JVM if the -jar option is used.

答案 1 :(得分:0)

是的,AbtPst是正确的。这是一个类路径问题。

这是类似的问题。 Does java -jar option alter classpath options

可执行JAR必须通过清单文件的Class-Path标头引用它所需的所有其他依赖JAR。如果使用-jar选项,则JVM将忽略环境变量CLASSPATH和命令行上指定的任何类路径。

通过gradle在jar的manifest文件中添加classpath解决了我的问题。

jar {
  manifest {
    attributes(
      "Class-Path": configurations.compile.collect { it.getName() }.join(' '))
  }
}