在撰寫Java程式的時候,常常會需要引入別人提供的Jar檔案。這些Jar檔案所包的Package,名稱可能會重複,造成編譯失敗,或是執行時候拋出型態不合的例外。此時除了反編譯Jar檔案,手動改掉Package名稱再重新編譯的方法外,還有一個更好的選擇,那就是使用JarJar直接下指令更改Jar檔案的Package名稱。
通常我們在命名Java的Package時,會把自己的網址倒過來寫,例如本站的網址為「magiclen.org」,所以本站所寫的Java程式,Package名稱就會以「org.magiclen」當開頭來命名。如果大家都照著這個規則開發Java程式的話,應該不會有重複問題才對的呀!我們都知道網址不可能會重複的嘛!事實上,Package名稱之所以會重複,不照規則命名只是其中一項原因。
拿Android開發環境來說,Android SDK本身包含了Apache和JSON的函式庫(Library),也就是說,在正常情況下,我們無法引入自己習慣使用的Apache或是JSON的函式庫版本,而被迫要遷就使用Android所提供的函式庫版本。如果執意將Jar引入到Android專案的話,就會有文章一開始提到的問題。因此,為了解決這個問題,我們必須將引入的Jar檔中的Package名稱給改掉,此時,就得借助JarJar的力量了。
JarJar
JarJar本身就是一支Java程式,可以到官網下載可執行的Jar檔,直接在命令列使用。
以下的JarJar命令,可以查看Jar檔內所含的Package名稱:
以Google Gson的Jar檔案為例,可以看到以下的資訊:
從strings的內容可以知道這個Jar檔的Package名稱都是以「com.google.gson」開頭。
要更改Jar檔的Package名稱,可以使用以下命令:
rulesFile為一個文字檔案路徑,inJar為要改名的Jar檔案路徑,outJar為改完後輸出的Jar檔案路徑。
rulesFile有三種指令,分別如下:
rule用來取代Package的名稱。
zap用來移除符合名稱的Package。
keep只會保留符合的Package名稱,其他的則會刪除。如果和zap一起使用,將會在zap執行完之後才執行。
pattern為要比對的字串,可以使用「*」和「**」來表示任意的Package名稱。「*」可以代表一層的Package,「**」可以代表多層的Package。
result為要取代成的字串,可以使用「@1」、「@2」這類的符號表示要使用第幾個pattern的「*」或「**」所代表的字串。
如果要將Jar檔內的「com.google.gson」名稱全都替換成「org.magiclen」,可以撰寫以下的rulesFile:
執行JarJar的process命令後,就可以得到已修正過Package名稱的Jar檔案啦!