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 を利用できました。