[S2JDBC]Maven2 surefire レポート作成時に ArrayIndexOutOfBoundsException (2)
cobertura がカバレッジ測定用のソースコードを埋め込む対象が、パラメータ化されたクラスを継承していると本件が発生するようです。
調査内容と結果
例えば s2jdbc-gen を使って USER テーブルから entity, names, および service を自動生成した場合、
- foo.entiry.User
- foo.entiry.UserNames
- foo.entiry.UserNames$_UserNames
- foo.service.AbstractService
- foo.service.UserService
が作られますが、それぞれのクラスについて cobertura によるバイトコードマニュピレーション後に getInterfaces() と getGenericInterfaces() を実行したところ、結果は下記のようになりました。
画面幅の都合上、パッケージ名は省略しています。
name | implements | extends | getInterfaces() | getGenericInterfaces() |
---|---|---|---|---|
User | Serializable | - | Serializable, HasBeenInstrumented | Serializable, HasBeenInstrumented |
UserNames | - | - | HasBeenInstrumented | HasBeenInstrumented |
UserNames$_UserNames | - | PropertyName |
HasBeenInstrumented | - |
AbstractService | - | S2AbstractService |
HasBeenInstrumented | - |
UserService | - | AbstractService |
HasBeenInstrumented | - |
パラメータ化されていないクラスを継承する例として、org.seasar.cubby.action.Action を継承するアクションクラスについても同様の調査を行いましたが、getInterfaces() と getGenericInterfaces() のどちらについても HasBeenInstrumented インタフェースを取得できました。
原因
net.sourceforge.cobertura.instrument.Main#addInstrumentationToArchive() で net.sourceforge.cobertura.coveragedata.HasBeenInstrumented インタフェースを組み込んでいるところまでは追ったのですが、その先は ObjectWeb で開発されている ASM の API を調べなければならず、継続して調査中です。
余談
net.sourceforge.cobertura.coveragedata.HasBeenInstrumented は何もメソッドが定義されていない、いわゆるマーカ・インタフェースという奴で、クラスのメタ情報をアノテーションで表現できるようになった java 5 以降では、やや邪道なインタフェースの使い方なのかもしれません。