Ste*_*eph 9 java logging executable-jar log4j2
使用可执行JAR文件时,我无法指定Log4j2配置文件位置.如果我将所有JAR分开,它可以正常工作,但是当我尝试将它们组合成一个可执行的JAR文件时,由于某种原因,log4j2.xml文件不会从命令行中获取.
我已经尝试了这两种指定位置的方法:
java -Djava.libary.path=..\bin -cp ..\config -jar MyApplication.jar
java -Djava.libary.path=..\bin -Dlog4j.configurationFile=..\config\log4j2.xml -jar MyApplication.jar
Run Code Online (Sandbox Code Playgroud)
这些都没有奏效.我还尝试将包含配置文件的目录添加到JAR清单文件中的类路径中:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.9.2
Created-By: 1.7.0_21-b11 (Oracle Corporation)
Main-Class: com.abc.MyApplication
Class-Path: ../config/
Run Code Online (Sandbox Code Playgroud)
我也没有成功使用这种方法.我有什么想法可能做错了吗?
在此先感谢您的帮助!
编辑
啊,我相信我误解了这个问题.最初,这是我在命令行输出中看到的错误:
ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.
Run Code Online (Sandbox Code Playgroud)
但是在我改变事物的某个时刻,错误消息发生了变化而我没有意识到这一点:
ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console...
Run Code Online (Sandbox Code Playgroud)
因此,我想通了,是即使可执行的JAR我是建设了包括log4j-core-2.1.jar和log4j-api-2.1.jarJAR文件在它的内部,并在MANIFEST文件中的类路径中,有一个问题.我编写我的ant文件以将库组合到我正在创建的单个JAR中的方式是成功复制目录和类文件,但由于某些原因没有复制其他类型,这显然也是必要的(例如Log4j-config .xsd,Log4j-events.dtd等).
为了解决这个问题,我改变了将我的Ant构建文件中的JAR合并到此的方式:
<jar destfile="${dist}/${jarName}" basedir="${classes}"
excludes=".svn">
<!-- Merge this JAR with all the JARs in the lib directory, so that
we are only creating one distribution JAR that includes all the
libraries that you need. -->
<fileset dir="${classes}" includes="**/*.class" />
<zipgroupfileset dir="${lib}" includes="**/*.jar" />
<!-- Specify the manifest file of the JAR -->
<manifest>
<attribute name="Main-Class" value="com.abc.MyApplication"/>
<attribute name="Class-Path" value=". ${manifest.classpath}"/>
</manifest>
</jar>
Run Code Online (Sandbox Code Playgroud)
这解决了问题并将所有文件从JAR复制到我新创建的JAR中.
解决此问题后,我上面发布的第二个命令用于指定配置文件的位置.(@rewolf如下所述,第一个命令不起作用,因为MANIFESTJAR中指定的类路径会覆盖命令行上指定的任何类路径.
感谢您的回复,他们肯定帮助我找到了解决错误的正确道路.
rew*_*olf 19
Java文档中没有很好解释的东西是,如果你使用的是可执行的Jar,它只会使用Manifest文件中指定的Class-Path.它不会听取-cp或--classpath论证.
-Dlog4j.configurationFile=directory/file.xml
绝对应该工作.考虑到你的斜线方向,我假设你在Windows上运行.您确定从正确的相对目录运行它吗?
更新
我刚刚在Windows中尝试过没有问题.我使用了以下清单:
Manifest-Version: 1.0
Built-By: andrew.flower
Build-Jdk: 1.7.0_67
Class-Path: lib/log4j-api-2.1.jar lib/log4j-core-2.1.jar
Created-By: Apache Maven 3.2.3
Main-Class: com.andrew_flower.test.Log4jTest
Archiver-Version: Plexus Archiver
Run Code Online (Sandbox Code Playgroud)
该Log4j2罐位于一个lib/目录中,log4j2.xml在conf/目录中.我执行了以下命令,它成功找到了配置.
java -Dlog4j.configurationFile=conf\log4j2.xml -jar log4j2test1-1.0-SNAPSHOT.jar
Run Code Online (Sandbox Code Playgroud)
我解决了在我从Eclipse创建的可运行Jar中指定log4j2配置位置的问题,方法是在我的java代码中包含它:
System.setProperty("log4j.configurationFile", "resources/log4j2.xml");
Run Code Online (Sandbox Code Playgroud)
我有一个包,所以我需要指定我的"resources"文件夹的路径(在Eclipse的"src"文件夹中):
System.setProperty("log4j.configurationFile", "com/company/app/resources/log4j2.xml");
Run Code Online (Sandbox Code Playgroud)
注意我的路径中没有包含"src",我认为这是"bin"文件夹中所需的路径:即在我的情况下"com/company/app/resources/log4j2.xml"
我的配置文件如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level - %msg%n"/>
</Console>
<RollingFile
name="RollingFile"
fileName="${sys:logFilename}"
filePattern="${sys:logFilename}-%d{yyyy-MM-dd}-%i.log">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level - %msg%n"/>
<Policies>
<SizeBasedTriggeringPolicy size="1 MB"/>
</Policies>
<DefaultRolloverStrategy max="10"/>
</RollingFile>
</appenders>
<loggers>
<root level="all">
<appender-ref ref="Console"/>
<appender-ref ref="RollingFile"/>
</root>
</loggers>
Run Code Online (Sandbox Code Playgroud)
另请注意,我通过将其包含在我的java代码中来动态分配滚动日志文件路径+名称"$ {sys:logFilename}":
System.setProperty("logFilename", "logs/myApp.log");
Run Code Online (Sandbox Code Playgroud)
为了使这两个动态System.setProperty赋值工作,他们需要在"getLogger"语句之前执行,所以我的java代码如下所示:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class MyTestLoggingClass {
public static Logger logger = null;
...................
setUpLogging();
...............
public static void setUpLogging() {
System.setProperty("log4j.configurationFile", "com/company/app/resources/log4j2.xml");
System.setProperty("logFilename", "logs/myApp.log");
logger = LogManager.getLogger(Logger.class.getName());
}
Run Code Online (Sandbox Code Playgroud)
}
在我的类的开头声明"logger"(但是在我的2个System.setProperty语句之前没有调用"getLogger")使我能够在其他方法中引用"logger".我不得不初始化它,因此我选择了"null"但后来用"getLogger"语句更新它 - 鉴于此我不能使它"最终"(只能分配一次)但可以使它静态 - 一个常量类变量.
我在构建路径中包含的2个log4j2罐子是:
log4j的-API-2.6.2.jar
log4j的核心 - 2.6.2.jar
对于可能有此问题的其他人...
因此,如果您的程序文件夹中有一个 log4j2.xml 用于您的 exampleApp,C:\Program Files\ExampleApp那么...
java.exe -Dlog4j.configurationFile=file://c:/program%20files/exampleapp/log4j2.xml -jar exampleApp.jar ...
Run Code Online (Sandbox Code Playgroud)
...应该管用
| 归档时间: |
|
| 查看次数: |
31519 次 |
| 最近记录: |