Java/Maven で「Xerces 地獄」に対処するには? 質問する

Java/Maven で「Xerces 地獄」に対処するには? 質問する

私のオフィスでは、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 など) をプロキシしているエンタープライズ ソフトウェアの場合はすぐに問題になります。

Artifactory によってプロキシされた xml-apis

たとえば、組織 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の が解決済みの依存関係として含まれます。

複数の xml-api による依存関係を解決しました

クラスローダー地獄

前述のように、JRE は JAXP RI で Xerces とともに出荷されます。すべての Xerces Maven 依存関係を または としてマークするのが望ましいですが<exclusion><provided>依存するサードパーティ コードは、使用している JDK の JAXP で提供されているバージョンで動作する場合と動作しない場合があります。さらに、サーブレット コンテナーで出荷される Xerces jar に対処する必要があります。これにより、いくつかの選択肢が残ります。サーブレット バージョンを削除して、コンテナーが JAXP バージョンで実行されることを期待しますか? サーブレット バージョンを残して、アプリケーション フレームワークがサーブレット バージョンで実行されることを期待する方がよいでしょうか? 上で概説した未解決の競合の 1 つまたは 2 つが製品に紛れ込むと (大規模な組織では簡単に発生します)、すぐにクラスローダー地獄に陥り、クラスローダーが実行時にどのバージョンの Xerces を選択しているのか、Windows と Linux で同じ jar を選択するかどうか (おそらくそうではない) が疑問になります。

解決策は?

<provided>すべての Xerces Maven 依存関係をまたは としてマークしようとしました<exclusion>が、成果物に多数のエイリアス ( xml-apisxercesxercesImplxmlParserAPIsなど) があるため、これを強制するのは困難です (特に大規模なチームの場合)。さらに、サードパーティのライブラリ/フレームワークは、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-betaMaven バージョンにすることはできません。classifier

おすすめ記事