4

我有一个可运行的 jar 文件。

我有一个 log4j.xml 文件位于同一目录中。

我的类路径包括“。”

env |grep CLASS
CLASSPATH=.;C:\Program Files (x86)\Java\jre6\lib\ext\QTJava.zip

但是当我运行时,java -jar myrunnable.jar我收到以下消息。

log4j:WARN No appenders could be found for logger (org.apache.commons.configuration.PropertiesConfiguration).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.

奇怪的是,如果我将该 jar 包装在一个 launch4j 可执行文件中,它会看到 log4j.xml 文件并使用它。

我确实去了错误消息中提到的常见问题解答页面。内容如下:

当无法找到默认配置文件 log4j.properties 和 log4j.xml 并且应用程序未执行显式配置时,会发生这种情况。log4j 使用 Thread.getContextClassLoader().getResource() 来定位默认配置文件,不直接检查文件系统。了解放置 log4j.properties 或 log4j.xml 的适当位置需要了解正在使用的类加载器的搜索策略。

我有点不明白我需要做什么才能让我的可运行 jar 看到 log4j.xml,而不是添加-Dlog4j.configuration=file:\\\\my\crazy\long\path\to\my\eclipse\workspace\target\directory\log4j.xml到命令行,这是一个 PITA 来输入。

如果我尝试类似java -Dlog4j.debug -Dlog4j.configuration=.\\log4j.xml -jar myrunnable.jar

log4j: Trying to find [.\\log4j.xml] using context classloader sun.misc.Launcher $AppClassLoader@265f00f9.
log4j: Trying to find [.\\log4j.xml] using sun.misc.Launcher$AppClassLoader@265f00f9 class loader.
log4j: Trying to find [.\\log4j.xml] using ClassLoader.getSystemResource().
log4j: Could not find resource: [.\\log4j.xml].

不同组合的相同结果log4j.xml./log4j.xml

如果有所不同,这是通过标准 slf4j-log4j 绑定使用 log4j 的 windows 7/java 7/64 位。

补充说明:

  • 尝试java -cp .不成功
  • 也试过java -cp .\\
  • 检查 jar 文件 META-INF\MANIFEST.MF 并且没有类路径条目
  • 这个特殊的 jar 是由 maven 使用 maven shade 插件生成的。

解决方案(某种)

根据 Dave Newton 在下面的回答,我更改了 MANIFEST.MF 文件以包含以下行:

Class-Path: ./

有了这个,我的 log4j.xml 文件就被正确地看到了。我正在使用 Maven Shade 插件来构建 jar 文件,因此添加 Class-Path 条目是配置ManifestResourceTransformer的问题。

<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
  <mainClass>my.runnable.Class</mainClass>
  <manifestEntries>
    <Class-Path>./</Class-Path>
  </manifestEntries>
</transformer>

我说“排序”已解决,因为虽然它确实输出了从我想要的 log4j.xml 文件配置的日志记录信息,但这意味着将该路径硬编码到我的 jar 中,并且任何使用我的 jar 的人都必须在安装目录中有 log4j.xml 或 log4j.properties . 我希望有一个更好的解决方案来提供标准和预期的结果(log4j.xml/log4j.properties 文件可以放在类路径上的任何位置),但是我今天所做的所有搜索似乎都不是案子。

我想我又遇到了另一个令人沮丧的问题,即 Java 的行为不直观,除了非常简单地解释它为什么会这样,还需要阅读整本书。

4

2 回答 2

2

当您使用 -jar 时,类路径将被忽略。

您可以将配置文件添加到清单Class-Path条目中,但请考虑提供路径。它可能需要是一个文件资源,否则它可能会尝试在 jar 的类路径值上找到它。

于 2013-06-19T23:59:29.463 回答
1

对于 Maven 中的 Eclipse 测试,我发现做的最简单的事情就是将log4j.xml. src/test/resources运行单元测试等时,它将被添加到类路径中。当我们在客户站点实际安装应用程序时,我们将文件放在 /etc/... 并用-Dlog4j.configuration.

关于为什么当前目录部分不适合您的最佳猜测是 Eclipse 可能将当前目录设置为您认为的其他目录。尝试按照此处的说明打印当前工作目录并检查它是否与您的想法相符。

更新:差点忘了。当您指定-jar类路径时,选项 ( -cp -classpath) 将被忽略。

-罐

执行封装在 JAR 文件中的程序。第一个参数是 JAR 文件的名称,而不是启动类名称。为了使此选项起作用,JAR 文件的清单必须包含格式为 Main-Class: classname 的行。在这里,classname 标识具有用作应用程序起点的 public static void main(String[] args) 方法的类。有关使用 Jar 文件和 Jar 文件清单的信息,请参阅 Jar 工具参考页面和 Java 教程的 Jar 跟踪。使用此选项时,JAR 文件是所有用户类的来源,其他用户类路径设置将被忽略。

于 2013-06-19T23:56:16.033 回答