Jetty + Seasar で LinkageError
S2JDBC を使用している Web アプリを Jetty 上で起動した場合に、以下のような java.lang.LinkageError が発生することがあります。
java.lang.LinkageError: loader constraint violation in interface itable initialization: when resolving method "org.seasar.extension.dbcp.impl.XAConnectionImpl.getXAResource()Ljavax/transaction/xa/XAResource;" the class loader (instance of org/mortbay/jetty/webapp/WebAppClassLoader) of the current class, org/seasar/extension/dbcp/impl/XAConnectionImpl, and the class loader (instance of
) for interface javax/sql/XAConnection have different Class objects for the type javax/transaction/xa/XAResource used in the signature
グーグル先生にお伺いすると、いっぱいヒットするのでどうやら既知の事柄らしいです。
Jetty が javax.transaction 等、javax 系の jar をそのままではうまく扱ってくれないことが原因らしいです。systemClasses として設定してあげればいいらしいです。
そんなわけで、http://ml.seasar.org/archives/seasar-user/2008-September/015788.html を参考に設定しました。
Jetty の起動パラメータとして設定ファイルを渡すか、Web アプリの WEB-INF 下に jetty-web.xml か web-jetty.xml という名前で設定ファイルを置いておけば OK みたいです。
pom.xml にごちゃごちゃ書くのが面倒だったので、WEB-INF/jetty-web.xml を下記のような内容で用意しました。
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd"> <Configure class="org.mortbay.jetty.webapp.WebAppContext"> <Set name="systemClasses"> <Array type="java.lang.String"> <Item>java.</Item> <Item>javax.</Item> <Item>org.mortbay.</Item> <Item>org.xml.</Item> <Item>org.w3c.</Item> <Item>org.apache.commons.logging.</Item> <Item>org.apache.log4j.</Item> </Array> </Set> </Configure>
これで、無事 S2JDBC を利用できました。