2009/3/12

幫jar檔瘦身 Remove Unused Classes

寫程式的時候,通常會使用很多 library ,但是一旦遇到要把程式以 JNLP 的方式,送到client端的時候,產生jar的大小就很重要了,以LGPL license來看,我們的程式可以連結到LGPL license的library,我們不一定要以一個一個獨立的jar來散佈library,我們可以把所有classes集合在一個jar檔裡面,只要我們沒有修改到原始程式,就應該符合license的規定。

所以我們可以把程式沒有使用到的 binary classes 都去掉,Open Source 授權的關係,我們不修改 library 原始程式,不使用obfuscator,但也能達到縮小 jar 的目的。

首先要準備一個 使用到的 classlist 檔案,在執行程式的時候,加上 -verbose:class 參數,ex: java -verbose: Test ,把結果輸出到一個 classlist.txt 檔案檔案裡面會有類似這樣的資料,這就表示JVM從commons-logging-1.1.1.jar裡面載入了一個 class org.apache.commons.logging.LogConfigurationException。
[Loaded org.apache.commons.logging.LogConfigurationException from file:/D:/testproject/lib/commons-logging-1.1.1.jar]

1. 把所有 library 的 jar 用 org.apache.tools.zip.ZipFile 解開到某個 release 的目錄
2. 把編譯的 class 程式,也複製到 release 目錄
3. 從剛剛的 classlist.txt 裡面,把使用到的 classes 名稱,收集在一個 hash 裡面
4. 用 org.apache.commons.io.FileUtils.iterateFiles 把 release 目錄裡面所有的 .class 都集合起來
5. 一個一個比對 是不是有在 classlist.txt 的 hash 裡面
6. 如果不存在就把這個 class 刪掉
7. 最後 再用 jar cvf ..\proejct.jar . 就可以產生一個去掉沒有使用到的 classes 的 jar