JARファイルから特定のクラスを除外するAntカスタムタグ
あるプロジェクトで、ビルド時にとあるOSSのJARファイルからクラスを除外するということをやっていたが*1、余りにも面倒なやり方で行っていたのでさくっとAntのカスタムタグを作成して自動化してみた。
これまでのやり方
- build.propertiesに除外するクラスパターンを書く
exclude.classes=org/example/Foo.class,\ org/example/Bar.class
- build.xmlで上記除外リストを利用してunjarタスクで除外しつつ解凍し、再びJARファイルにパッケージングする。
<target name="default" depends="depends" description="description"> <unjar src="target/base.jar" dest="work"> <patternset> <exclude name="${exclude.classes}" /> </patternset> </unjar> <jar destfile="target/result.jar" basedir="work" /> </target>
このやり方だと、差し替えたいクラスが増える度にbuild.propertiesをメンテナンスする必要がある。面倒だし、記入漏れやミスが発生することが過去何回もあった。
Antカスタムタグでの方法
そもそも除外したいクラスは別途JARファイルとしてあるので、わざわざbuild.propertiesに書かなくてもJARファイルから除外リストを自動すれば良い。というわけでAntタスククラスを作成。
使い方
- taskdefを定義し、classpath属性にビルドしたant-tasks-ext-1.0.jarを指定する。Ant本体のJAR(ant-1.7.0.jar)も合わせて指定する。resource属性にはantlib.xmlを指定する。
- 実際に使うところでは、excludejarタグを記述する。
- destfile: 編集後の出力するJARファイルを指定する。
- basefile: 編集したいJARファイルを指定する。
- excludefile: 除外したいクラスを持つJARファイルを指定する。
- autoclean: workディレクトリを自動削除する場合はtrueを指定する。無指定の場合はデフォルトfalse。
- work: 作業用ディレクトリを指定する。無指定の場合は、OSのtmpディレクトリ(java.io.tmpdir)が自動的に使われる。
記述例は以下。
<?xml version="1.0" encoding="UTF-8"?> <project name="project" default="default"> <taskdef classpath="lib/ant-tasks-ext-1.0.jar;lib/ant-1.7.0.jar" resource="antlib.xml" /> <target name="default"> <excludejar destfile="target/result.jar" basefile="target/base.jar" excludefile="target/exclude.jar" autoclean="true" work="./work" /> </target> </project>
これでようやく除外リストのメンテナンスから解放される!!
*1:そもそも何故除外していたかいうと、一部のクラスだけ改修して別のJARファイルに格納して利用していたのだが、同名クラスが存在すると環境によってはロード順が異なり意図しない動作になるらしいとのこと。そこでAntで一度除外したいクラスを除いて解凍し、再パッケージするという運用になっていた。