Ant 中 *Log4j.properties 找不到文件的問題

 在用 Ant 進行構建,部署,運行過程當中,發現一小問題,就是在運行時老是提示「系統找不到指定的文件」。害得我花了很多時間,最後終於弄清楚了問題的緣由。如下的錯誤代碼(貼出來好讓後面的人更容易找到這樣貼子。:))html

[java] log4j:ERROR Could not read configuration file [HelloWroldLog4j.properties].
[java] java.io.FileNotFoundException: HelloWroldLog4j.properties (系統找不到指定的文件。)
[java]     at java.io.FileInputStream.open(Native Method)
[java]     at java.io.FileInputStream.<init>(FileInputStream.java:106)
[java]     at java.io.FileInputStream.<init>(FileInputStream.java:66)
[java]     at org.apache.log4j.PropertyConfigurator.doConfigure(PropertyConfigurator.java:316)
[java]     at org.apache.log4j.PropertyConfigurator.configure(PropertyConfigurator.java:342)
[java] H:\jstudy\ant\use_log4j\build\jar
[java] File:  true
[java]     at antstudy.HelloWorld.main(Unknown Source)
[java] log4j:ERROR Ignoring configuration file [HelloWroldLog4j.properties].
[java] log4j:WARN No appenders could be found for logger (antstudy.HelloWorld).
[java] log4j:WARN Please initialize the log4j system properly.


  因爲文件中用到的PropertyConfigure.configure(String fileName),最終仍是利用了FileInputStream來讀取配置文件的,因此fileName與FileInputStream構造時的fileName是相同的。因而我把問題簡化爲用 Ant 來進行只包括 FileInputStream 類的簡單的代碼,出現了相同問題。因爲使用了相對路徑,因此只要能夠確認當前的目錄,就能夠解決問題了。利用 System.getProperty("user.dir") 終於找出來,當前用戶工做目錄是 Ant 的 build.xml 的路徑。在查看了Ant 的文檔, Java 任務能夠設置 dir 屬性來修改 JAVA 用戶工做目錄,固然要把 Java 任務的 fork 設置爲 true。問題解決!

  總結,問題的根本緣由仍是 Java 工做目錄的設置
。在用 Ant 進行執行 Java 任務時,JAVA用戶工做目錄是 builde.xml 全部的目錄(若是沒有修改的話),我想一般遇到我這樣問題的人,都沒有修改Java 任務的工做目錄。

  還有一個小問題沒有獲得解決,就是讓 Ant 打包之後,這些配置文件怎麼處理, *.properties 文件應不該該放到Jar包中呢?若是放在包中,
java

  1. *.properties文件將不能再進行手動設置了,缺少的其配置的靈活性。
  2. 我不知道該怎麼去訪問這個文件了,我目前的水平對這個一點也沒辦法,或者說要實現起來比較複雜。

  個人作法是,把當前工做目錄設置到Jar包所在的目錄,而且把*.properties文件複製到這個目錄下面,也就,不對*.properties 文件打包。

  不知道實際工做中是怎麼解決這樣的問題的。但願有人會回答個人這個問題,先謝過了。

  基本上找到了上面遺留問題的解決方法[續上]:
  也就是 Jar 包中的文件的讀取,在CSDN中有這樣的貼子。能夠去看看,討論得很詳細:
如何讀取自身Jar包中的文件 部份內容節選以下:
 apache

   在編寫完Java程序後,打包成Jar時發佈,會發現找不到Jar文件中的圖片和文本文件,其緣由是程序中載入圖片或文本文件時,使用了以當前工做路徑爲基準的方式來指定文件和路徑。這與用戶運行Jar包時的當前工做路徑並不一致。

問題分析:

   例如:以Windows爲例說明,如下是開發項目「AAA」的部分代碼,開發和調試時的根路徑爲D:\aaa,這樣程序運行時當前路徑爲"D:\aaa",你們能夠用System.getProperty("user.dir")方法求證當前用戶工做路徑。

併發

//下面代碼使用了基於當前工做路徑的方式指定了文件對象
File  imageFile  =  new  File("/images/sample.gif");
ImageIcon  imageIcon  =  new  ImageIcon(File.toURI);
File  iniFile  =  new  File("/conf.ini");
FileInputStream  fileInputStream  =  new  FileInputStream(iniFile.toURI);
/*
  *這樣程序會去找如下兩個文件:
  *    D:\aaa\images\sample.gif
  *    D:\aaa\conf.ini
  */


   以上的代碼應用絕對路徑信息指定了文件對象,在開發和調試期(未打包前),是沒有問題的,但在打包後,因爲全部圖片文件和文本文件都將打包到Jar文件中,因爲System中的"user.dir"屬性發生了變化,會形成用絕對路徑的方式沒法找到Jar文件中包含路徑和文件。例如你們將上面的項目 「AAA」中的全部類文件、圖片文件和文本文件等打包爲E:\aaa.jar文件併發布,在用戶執行該aaa.jar中的程序時,當前路徑取決於用戶運行該程序的當前路徑。

例如:  在「E:\」目錄下運行該程序:

app

E:\> java  -jar  aaa.jar



     此時用戶的當前路徑(System的user.dir屬性)是「E:\」,而非開發者所指望的「E:\aaa」,因此會按如下路徑來搜索文件:
 
    E:\images\sample.gif
    E:\conf.ini

    可是全部的圖片和文本文件包含在E:\aaa.jar文件中,因此會導致程序沒法正常運行。

問題解決:

   爲了解決上述問題,推薦採用Java自己以類爲基準的路徑搜索方式。
  
   例如:ui

/*
  *如下代碼採用了以當前類爲基準的路徑指定方式。下面這行代碼在運行時,會
  *在jar文件中的根路徑,搜索程序中用到的文件。
*/
Reader reader = new InputStreamReader(
        getClass().getResourceAsStream("/image/Environment.ini"));
ImageIcon i = new ImageIcon(getClass().getResource("/image/b1.gif"));


   以上兩行代碼採用了下面兩條Java語句:spa

getClass().getResourceAsStream("FileName");
getClass().getResource("File");


   含有這種代碼的程序在運行時,以類(類路徑)爲基準,而不依賴當前路徑(System中的user.dir)。

   注意:上面的路徑"/image/Environment.ini"若是寫成"image/Environment.ini",將表示在類同路徑下的路徑(className/image/Environment.ini),這須要您必須將圖片和文本等文件的保存路徑,和程序中指定的路徑二者保持一致。操作系統

maquan

> 什麼文件能夠?  .bat 不行的話. . 
> 哪些文件是能夠的?  image.?  or?

問題的本質是這樣的:若是你要用本身的程序去讀文件,什麼類型的文件都同樣能夠讀到(就用你說的 getResource());可是,.BAT 文件是給操做系統用的,操做系統並不支持從 jar 文件裏運行一個 BAT 文件。

因此,若是你必定要把 BAT 文件打到 jar 包裏,那隻能本身寫程序讀出這個文件的內容,再寫到一個操做系統能看到的地方(也就是寫到硬盤上的一個文件裏),再讓操做系統去運行它。

BTW: JAR 的意思就是 Java ARchive,顧名思義,就像老紫竹說的,「應該把非java文件放到外面」。

.net

相關文章
相關標籤/搜索