本文討論的是非web項目中java程序的路徑問題。
在咱們編寫的Java程序中,須要絕對路徑來定位到當前程序所在的路徑。咱們獲取了這個絕對路徑的變量值後,傳遞給Log4j日誌框架,從而實現輸出日誌路徑是動態的。
具體來講,是實現下面的預期。
1 當不在程序所在的目錄下執行jar文件時,程序中的絕對路徑仍然能生效。(即不是指向用戶目錄)。
2 實現Log4j輸出的日誌文件可以位於程序所在的目錄。(不須要額外的手工指定程序所在目錄,動態的實現)。java
1 絕對路徑的獲取。
2 帶依賴jar包的打jar包與程序路徑問題。
3 獲取了絕對路徑的變量值後,如何傳遞給Log4j日誌框架,與相關的配置。git
問題1 用下面的代碼能夠獲取程序的絕對路徑。github
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)便可,以下圖所示。==> finish。web
注意事項:對於打成帶有第三方依賴包的jar包時,Library handling選擇第一項(將依賴的jar解壓出來變成class放進你生成的jar),如上圖。緣由:選擇第二項時,絕對路徑獲取的代碼輸出爲null。app
String projectDir = 所在類名.class.getClass().getResource("/").getPath(); System.out.println(projectDir); // 當Library handling選擇第二項時,的輸出 null;
1 log4j.properties文件中的配置說明,在log4j.properties文件中,使用${系統變量名}來引用變量(絕對路徑),示例以下。框架
log4j.appender.file.File=${base.dir}mylog5.log
2 Java程序中的處理。eclipse
// 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包,都能正常的輸出日誌文件。
緣由:ui
// 獲取絕對路徑 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中,日誌無法正常執行輸出。
因此說,這個是正常現象,不影響咱們打包出的jar正常的輸出日誌文件到指定目錄。
存放絕對路徑的系統變量,是會被Log4j加載,且生效了。測試代碼以下:lua
// 存放絕對路徑的系統變量,被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
目錄下的文件讀取有影響嗎?
問題答案:沒有。使用獲取的絕對路徑+文件名,即爲src目錄下文件的絕對路徑。這個你們能夠作個小實驗。這裏就不展開了。
https://github.com/chuzhixing...
https://blog.csdn.net/qq_2180... (eclipse 導出可運行jar包時三種Library handling的區別 - 小藍的博客 - CSDN博客)