私のオフィスでは、Xerces という言葉を口にするだけで、開発者から殺意に満ちた怒りがわき起こります。SO の他の Xerces の質問をざっと見たところ、Maven ユーザーのほとんど全員が、この問題に一度は「悩まされている」ようです。残念ながら、この問題を理解するには、Xerces の歴史に関する知識が少し必要です...
歴史
Xerces は、Java エコシステムで最も広く使用されている XML パーサーです。Java で記述されたほぼすべてのライブラリまたはフレームワークは、何らかの形で (直接ではないにしても、推移的に) Xerces を使用しています。
Xercesの瓶は、公式バイナリ現在に至るまで、バージョン管理されていません。たとえば、Xerces 2.11.0 実装 jar は
xercesImpl.jar
ではなく という名前ですxercesImpl-2.11.0.jar
。XercesチームMavenを使用しないつまり、公式リリースをアップロードしないということですメイヴンセントラル。
ゼクセスはかつて単一の瓶として放出される(
xerces.jar
) でしたが、2 つの jar に分割され、1 つには API (xml-apis.jar
) が含まれ、もう 1 つにはそれらの API の実装 (xercesImpl.jar
) が含まれます。多くの古い Maven POM は、依然として への依存関係を宣言していますxerces.jar
。過去のある時点で、Xerces も としてリリースされましたがxmlParserAPIs.jar
、一部の古い POM もこれに依存しています。Maven リポジトリに xml-apis と xercesImpl の jar をデプロイする人によって割り当てられるバージョンは、多くの場合異なります。たとえば、どちらも Xerces 2.8.0 からのものであるにもかかわらず、xml-apis にはバージョン 1.3.03 が、xercesImpl にはバージョン 2.8.0 が与えられることがあります。これは、xml-apis の jar に、それが実装する仕様のバージョンをタグ付けすることが多いためです。この詳細について、非常にわかりやすい、しかし不完全な内訳があります。ここ。
問題を複雑にしているのは、Xerces が、JRE に含まれる Java API for XML Processing (JAXP) のリファレンス実装で使用される XML パーサーであることです。実装クラスは名前空間で再パッケージ化される
com.sun.*
ため、一部の JRE では利用できない可能性があるため、直接アクセスするのは危険です。ただし、Xerces のすべての機能がjava.*
およびjavax.*
API 経由で公開されるわけではありません。たとえば、Xerces のシリアル化を公開する API はありません。混乱をさらに複雑にしているのは、ほとんどすべてのサーブレット コンテナー (JBoss、Jetty、Glassfish、Tomcat など) の 1 つ以上の
/lib
フォルダーに Xerces が同梱されていることです。
問題点
紛争解決
上記の理由の一部 (あるいはすべて) により、多くの組織は POM で Xerces のカスタム ビルドを公開して使用しています。これは、小さなアプリケーションがあり、Maven Central のみを使用している場合はそれほど問題にはなりませんが、Artifactory または Nexus が複数のリポジトリ (JBoss、Hibernate など) をプロキシしているエンタープライズ ソフトウェアの場合はすぐに問題になります。
たとえば、組織 A はxml-apis
次のように公開する場合があります。
<groupId>org.apache.xerces</groupId>
<artifactId>xml-apis</artifactId>
<version>2.9.1</version>
一方、組織 B は次jar
のように同じことを公開する可能性があります。
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
<version>1.3.04</version>
B のjar
バージョンは A のバージョンよりも低いですがjar
、 が異なるため、Maven はこれらが同じ成果物であることを認識しませんgroupId
。したがって、競合解決を実行できず、両方jar
の が解決済みの依存関係として含まれます。
クラスローダー地獄
前述のように、JRE は JAXP RI で Xerces とともに出荷されます。すべての Xerces Maven 依存関係を または としてマークするのが望ましいですが<exclusion>
、<provided>
依存するサードパーティ コードは、使用している JDK の JAXP で提供されているバージョンで動作する場合と動作しない場合があります。さらに、サーブレット コンテナーで出荷される Xerces jar に対処する必要があります。これにより、いくつかの選択肢が残ります。サーブレット バージョンを削除して、コンテナーが JAXP バージョンで実行されることを期待しますか? サーブレット バージョンを残して、アプリケーション フレームワークがサーブレット バージョンで実行されることを期待する方がよいでしょうか? 上で概説した未解決の競合の 1 つまたは 2 つが製品に紛れ込むと (大規模な組織では簡単に発生します)、すぐにクラスローダー地獄に陥り、クラスローダーが実行時にどのバージョンの Xerces を選択しているのか、Windows と Linux で同じ jar を選択するかどうか (おそらくそうではない) が疑問になります。
解決策は?
<provided>
すべての Xerces Maven 依存関係をまたは としてマークしようとしました<exclusion>
が、成果物に多数のエイリアス ( xml-apis
、xerces
、xercesImpl
、xmlParserAPIs
など) があるため、これを強制するのは困難です (特に大規模なチームの場合)。さらに、サードパーティのライブラリ/フレームワークは、JAXP バージョンまたはサーブレット コンテナによって提供されるバージョンでは実行されない可能性があります。
Maven でこの問題に最も効果的に対処するにはどうすればよいですか? 依存関係を細かく制御し、階層化されたクラスローディングに頼る必要がありますか? すべての Xerces 依存関係をグローバルに除外し、すべてのフレームワーク/ライブラリで JAXP バージョンを使用するように強制する方法はありますか?
更新: Joshua SpiewakがXercesビルドスクリプトのパッチ版をアップロードしました。ゼレセJ-1454Maven Central へのアップロードが可能になります。この問題に投票/監視/貢献して、この問題を完全に解決しましょう。
ベストアンサー1
2013年2月20日以降、Maven CentralにXerces 2.11.0 JAR (およびソースJAR)が存在します。Maven Central の Xercesなぜ解決しないのか不思議だhttps://issues.apache.org/jira/browse/XERCESJ-1454...
使用したのは以下のものです:
<dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>2.11.0</version>
</dependency>
すべての依存関係が正常に解決されました - 適切にxml-apis-1.4.01
!
そして最も重要なこと (そして過去には明らかではなかったこと) は、Maven Central の JAR が公式Xerces-J-bin.2.11.0.zip
ディストリビューションの JAR と同じであることです。
しかし、バージョンを見つけることができませんでした。追加の依存関係があるため、xml-schema-1.1-beta
Maven バージョンにすることはできません。classifier