S2JDBC + S2JUnit4でハマる
S2JDBCのエンティティのテストケースをS2JUnit4で書いてみたら、大いにハマった。
org.seasar.framework.beans.IllegalPropertyRuntimeException: [ESSR0059]クラス(org.seasar.framework.jpa.impl.PersistenceUnitManagerImpl)のプロパティ(entityManagerProvider)の設定に失敗しました。理由はorg.seasar.framework.container.IllegalAutoBindingPropertyRuntimeException: [ESSR0080]クラス(org.seasar.framework.jpa.impl.EntityManagerProviderImpl)のプロパティ(dataSourceFactory)の自動設定に失敗しました at org.seasar.framework.container.assembler.AbstractBindingTypeDef.getValue(AbstractBindingTypeDef.java:297) at org.seasar.framework.container.assembler.AbstractBindingTypeDef.bindAuto(AbstractBindingTypeDef.java:164) at org.seasar.framework.container.assembler.BindingTypeMustDef.doBind(BindingTypeMustDef.java:45) at org.seasar.framework.container.assembler.AbstractBindingTypeDef.bind(AbstractBindingTypeDef.java:91) at org.seasar.framework.container.assembler.AccessTypeFieldDef.bind(AccessTypeFieldDef.java:50) (以下、たくさん続く…)
Seasar2のソースコードを漁ってみたところ、自動設定に失敗しているdataSourceFactoryのコンポーネント定義は、jdbc-extension.diconに存在することがわかった。これは通常jdbc.diconからincludeされているはずなのだが、Doltengが吐き出したjdbc.diconにはこれがincludeされていない。
jdbc-extension.diconはDAOサポートに必要とされているらしいのだが、今回のようにS2JDBCを使うことを選択した場合は不要という判断なのかもしれない。しかし、S2JUnit4はDBアクセス関係のユーティリティで利用しているのだろう、とか憶測でモノを言ってみる。
とにかく、jdbc-extension.diconをincludeさせてみた。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN" "http://www.seasar.org/dtd/components24.dtd"> <components namespace="jdbc"> <include path="jta.dicon"/> <include path="jdbc-extension.dicon"/> <component name="xaDataSource" class="org.seasar.extension.dbcp.impl.XADataSourceImpl"> ...
これで先ほどの例外はthrowされなくなった。
…なんかあっさりと書いているが、この件で一週間は悩んでいた。依存関係の解消にはいつも手間取る。
追記
id:taedium氏からおそろしいスピードでコメントをいただいたので、試してみた。曰く、「S2JDBCを使うのであれば、javaee5.diconではなくapp.diconをincludeしたほうがよい」なるほど−。
s2junit4を、こう書けばいいのか。
<component class="org.seasar.framework.unit.impl.ConfigFileIncluderImpl"> <initMethod name="addConfigFile"> <arg>"app.dicon"</arg> </initMethod> <initMethod name="addConfigFile"> <arg>context.testClassShortName + ".dicon"</arg> </initMethod> ...
もっとも、諸事情あってRootDiconをapp.diconにしているテストケースがあるので、こういう対応もした*1。
@RunWith(Seasar2.class) @RootDicon("app.dicon") public class ... ctx.setAutoInclude(false); // ctx.include("javaee5.dicon"); ctx.include("dbtest.dicon"); // 自前のdicon
これで、jdbc.diconからjdbc-extension.diconのincludeを取り除いても、ちゃんと動くようになった。
これだけ速攻で回答できるってことは、きっとありがちなケースなんだろうなぁ(汗)ともあれ、ありがとうございました。Seasar2始めてから日記も拝見しています。