星期日, 9月 30, 2012

JasperReports compile與JDK版本之問題.

前陣子想說很久沒post文章, 要來回顧一下, 回到 Blogger, 看到有人引用我的文章.
http://michaelyang1988-hotmail-com.iteye.com/blog/1218781
突然覺得, 有幫助到人的感覺真的很不錯, 也給了我些許的動力再寫一些分享...

下面就來分享一下之前碰過 JasperReports 的問題之解決方式...

一般JasperReports使用方式, 會先使用 JDK 去 compile JasperReports 的設計檔之後, 在程式中使用 compile 出來的 jasper 檔案讓 jasperreports去進行產生報表的功能.

但若使用 JDK 1.5 compile的jasper檔案, 若到 JRE 1.4 的版本去運作時, 馬上會出現 UnsupportedClassVersionError 的 Error.

所以必須確定執行環境的 JRE 版本必須小於 compile 的 jasper 版本.

由於客戶端的 JRE, 從 1.4 ~ 1.6 都有, 很多客戶覺得沒事就不要升級.
因此最保險的做法就是確保都用 JDK 1.4 去進行 compile 即可.

而現在只為了這一個功能而去裝 JDK1.4似乎又小題大作.且若忘了用JDK1.4 compile, 到客戶端才會發現此問題...確實造成不少困擾...

用過 JDK 應該都知道, JDK 可以透過下參數的方式 compile 出之前的版本, 而不需要真正裝 JDK 1.4~
由於 JasperReports 也是透過 JDK 進行 compile, 理應也可以下參數來解決. 但查了一下, 似乎沒人有此需求, 經查程式, 連現在最新的 JasperReports 4.7.1 也都無此功能. (我則是使用JasperReports0.5.3, 好悠久的歷史...)

所以最快的方式就是去找出 JasperReports compile 的程式手動加入參數即可.
用關鍵字去找, 很快找出其邏輯...
在 JRDefaultCompiler.java 中可看到, 會依 JRJdk13Compiler, JRJdk12Compiler, JRJavacCompiler 的順序去建立 Compiler 物件. 由於我們使用 sun 1.4 以上之 jdk, 因此只需要調整 JRJdk13Compiler 即可.

在JRJdk13Compiler.java 101 行左右可看到如下:
  public String compileClass(File sourceFile, String classpath) throws JRException
  {
    String[] source = new String[3];
    source[0] = sourceFile.getPath();
    source[1] = "-classpath";
    source[2] = classpath;

找到程式後, 修改就很容易了, 改成如下:
  public String compileClass(File sourceFile, String classpath) throws JRException
  {
    String[] source = new String[7];
    source[0] = sourceFile.getPath();
    source[1] = "-classpath";
    source[2] = classpath;
    source[3] = "-source";
    source[4] = "1.4";
    source[5] = "-target";
    source[6] = "1.4";

重新打包好 jasperreports 的 jar 後, 使用 jdk 1.6 進行 compile, 在 jdk1.4 上 run, 運作成功.
當然此改法是使用 hard code 方式, 對我已經很夠用. 若是要彈性一點, 可加入一些 system properties 或多傳參數等方式來進行判斷是否使用此邏輯等等...


0 Comments:

張貼留言

<< Home