環境は Linux 上の WAS 6.1 で、xercesImpl.jar のクラスを使用する Web アプリケーションをデプロイします。
会社のポリシーの制限により、アプリは次の設定で展開する必要があります。
Class Loader Order
Classes loaded with parent class loader first
-> Classes loaded with application class loader first
WAR class loader policy
Class loader for each WAR file in application
-> Single class loader for application
WAR ファイルには、xercesImpl.jar のコピーが含まれています。これは、アプリがコンパイルされたときにクラスパスにあったものと同じです。
webapp を起動するときに、Spring がその構成を解析しようとすると、以下がスローされます。
java.lang.VerifyError: class loading constraint violated
(class: org/apache/xerces/jaxp/DocumentBuilderImpl
method: parse(Lorg/xml/sax/InputSource;)Lorg/w3c/dom/Document;)
これまでの分析
WAS は org.apache.xerces.jaxp.DocumentBuilderImpl の実装を提供しているようです。これは、WAR ファイルから xercesImpl.jar を削除しても同じエラー (ClassNotFoundException ではない) が発生する可能性があるためです。したがって、WAS は、コンパイル済みのクラス ファイル内の参照と互換性のない独自のコピーを使用して参照を解決しているようです。ただし、私が見つけることができる「xercesImpl.jar」の唯一の他のインスタンス (アプリでデプロイされたコピーを除く) は
deploytool
、アプリ サーバーの外部にあるように見える directory にあります。
WASのすべてのjarファイル(1300個すべて)をスキャンしました
for i in `find . -name \*.jar`; do jar tvf $i|grep -qi xerces && echo $i ; done
./java/jre/lib/xml.jar
のすべてのクラスが含まれていることがわかったorg.apache.xerces.*
ので、これはクラスローダーが参照を解決している場所である可能性があります。
ここに奇妙な部分があります:
「親クラスローダーを最初に」に変更すると、例外は表示されません。これは、予想される動作に反します。「最初にアプリケーション クラスローダー」を使用すると、提供された xercesImpl.jar が使用され、「親クラスローダーが最初に」設定されている場合にのみ WAS のバージョンが使用されると予想されます。これは、私たちが実際に見ているものとは逆のように見えます。
質問:
クラスローダ委任設定は、上記の情報とどのように相互作用して、観察された動作をもたらしていますか?