本文讨论的是非web项目中java程序的路径问题。
在我们编写的Java程序中,需要绝对路径来定位到当前程序所在的路径。我们获取了这个绝对路径的变量值后,传递给Log4j日志框架,从而实现输出日志路径是动态的。
具体来说,是实现下面的预期。
1 当不在程序所在的目录下执行jar文件时,程序中的绝对路径仍然能生效。(即不是指向用户目录)。
2 实现Log4j输出的日志文件能够位于程序所在的目录。(不需要额外的在程序之外指定,动态的实现)。
1 绝对路径的获取。
2 带依赖jar包的打jar包与程序路径问题。
3 获取了这个绝对路径的变量值后,如何传递给Log4j日志框架,与相关的配置。
问题1 用下面的代码可以获取程序的绝对路径。
String projectDir = 所在类名.class.getClass().getResource("/").getPath(); System.out.println(projectDir); // 在eclipse中运行输出结果示例 /E:/workspace_set/big_data_workspace/DemoTest/bin/ // 打成jar包运行的输出结果示例 /E:/workspace_set/big_data_workspace/DemoTest
Export ==> Java ==> Runnable Jar file ==>
在luanch configuration中选择你的main方法所在的类,在Export destination中输入类名,Library handling选择第一项(extract required libraries into genetated jar)即可,如下图所示。
注意事项:对于打成带有第厂方依赖jar包的jar包时,Library handling选择第一项(将依赖的jar解压出来变成class放进你生成的jar),如下图。
原因:选择第二项时,绝对路径获取的代码输出为null。
String projectDir = 所在类名.class.getClass().getResource("/").getPath(); System.out.println(projectDir); // 当Library handling选择第二项时,的输出 null;
1 log4j.properties文件中的配置说明,在log4j.properties文件中,使用${base.dir}来引用变量(绝对路径),如下。
log4j.appender.file.File=${base.dir}mylog5.log
2 Java程序中的处理。
// 1 在logger私例化之前,执行下面的代码 // 获取绝对路径 String projectDir = 所在类名.class.getClass().getResource("/").getPath(); // 将绝对路径赋值给系统变量 System.setProperty("base.dir", projectDir); // 2 Read the configuration file configFilename if it exists. // 这里相当于重新加载,让绝对路径的配置生效; PropertyConfigurator.configure(projectDir + "log4j.properties"); // 存放绝对路径的系统变量,被Log4j加载的测试 // 获取FileAppender对象 FileAppender appender= (FileAppender) Logger.getRootLogger().getAppender("file"); // 输出示例:/E:/workspace_set/big_data_workspace/DemoTest/bin/mylog5.log System.out.println(appender.getFile()); // 3 实例化Logger; Logger logger = Logger.getLogger(当前类名.class);
经过上述步骤,即可完成了log4j的正常输出。
下面是在使用过程中遇到的问题的解释。
现象:在eclipse中执行时,会没有输出日志的文件。但是,打包出去(打包的话,按照本文的操作步骤去打jar包。),无论是在程序所在的目录下,还是在其它的目录下,执行这个jar包,都能正常的输出日志文件。
原因:
// 获取绝对路径 String projectDir = 所在类名.class.getClass().getResource("/").getPath(); System.out.println(projectDir); // 在eclipse中执行的输出值 projectDir=/E:/workspace_set/big_data_workspace/DemoTest/bin/ // 打成jar包的输出值 projectDir=/E:/workspace_set/big_data_workspace/DemoTest/
如上, /E:/workspace_set/big_data_workspace/DemoTest/bin/
,这个路径找不到,所以在eclipse中,日志没法正常执行输出。
所以说,这个是正常现象,不影响我们使用。
但是,存放绝对路径的系统变量,是会被Log4j加载,且生效了。测试代码如下:
// 存放绝对路径的系统变量,被Log4j加载的测试 // log4j.properties文件中的配置假设如下: // log4j.appender.file.File=${base.dir}mylog5.log // 观测代码 String projectDir = TestLog2.class.getClass().getResource("/").getPath(); PropertyConfigurator.configure(projectDir + "log4j.properties"); //获取FileAppender对象 FileAppender appender= (FileAppender) Logger.getRootLogger().getAppender("file"); System.out.println(appender.getFile()); // 输出值结果示例: /E:/workspace_set/big_data_workspace/DemoTest/bin/mylog5.log
问题描述:获取的绝对路径在eclipse中执行,由于获取的路径中带有 bin
这个字段,对于位于 src
目录下的文件读取有影响吗?
问题答案:没有,这个大家可以做个小实验。这里就不展开了。
https://github.com/wanderLure...
https://blog.csdn.net/qq_2180... (eclipse 导出可运行jar包时三种Library handling的区别 - 小蓝的博客 - CSDN博客)