Java9でのJAXBExceptionのNoClassDefFoundErrorの処理
1. 序章
Java 9にアップグレードしようとした人は、以前のバージョンのJavaで機能していたコードをコンパイルするときに、ある種のNoClassDefFoundErrorを経験した可能性があります。
この記事では、一般的な欠落しているクラス JAXBException と、それを解決するためのさまざまな方法について説明します。 ここで提供されるソリューションは、通常、Java9へのアップグレード時に欠落している可能性のあるすべてのクラスに適用できます。
2. Java9がJAXBExceptionを見つけられないのはなぜですか?
Java 9の最も議論されている機能の1つは、モジュールシステムです。 Java 9モジュールシステムの目標は、コアJVMクラスと関連プロジェクトをスタンドアロンモジュールに分解することです。 これにより、実行に必要な最小限のクラスのみを含めることで、フットプリントが小さいアプリケーションを作成できます。
欠点は、多くのクラスがデフォルトでクラスパスで使用できなくなっていることです。 この場合、クラス JAXBException は、java.xml.bindという名前の新しいJakartaEEモジュールの1つにあります。 このモジュールはコアJavaランタイムでは必要ないため、デフォルトではクラスパスでは使用できません。
JAXBException を使用するアプリケーションを実行しようとすると、次のようになります。
NoClassDefFoundError: javax/xml/bind/JAXBException
このを回避するには、java.xml.bindmoduleを含める必要があります。 以下で説明するように、これを実現するには複数の方法があります。
3. 短期的な解決策
JAXB APIクラスがアプリケーションで使用可能であることを確認する最も簡単な方法は、を追加することです。–add-modulesコマンドライン引数を使用します。
--add-modules java.xml.bind
ただし、これはいくつかの理由で適切な解決策ではない可能性があります。
まず、 –add-modules引数もJava9の新機能です。 複数のバージョンのJavaで実行する必要があるアプリケーションの場合、これにはいくつかの課題があります。 アプリケーションが実行されるJavaバージョンごとに1つずつ、ビルドファイルの複数のセットを維持する必要があります。
これを回避するには、古いJavaコンパイラの -XX:+IgnoreUnrecognizedVMOptionsコマンドライン引数を使用することもできます。
ただし、これは、タイプミスやスペルミスのある引数が私たちの注意を引くことがないことを意味します。 たとえば、最小または最大のヒープサイズを設定し、引数名を誤って入力しようとしても、警告は表示されません。 アプリケーションは引き続き起動しますが、予想とは異なる構成で実行されます。
次に、 –add-modules オプションは、将来のJavaリリースで非推奨になります。 つまり、Javaの新しいバージョンにアップグレードした後のある時点で、不明なコマンドライン引数を使用するという同じ問題に直面し、問題に再度対処する必要があります。
4. 長期的な解決策
さまざまなバージョンのJavaで機能し、将来のリリースで壊れない、より優れたアプローチがあります。
解決策は、Mavenなどの依存関係管理ツールを利用することです。 このアプローチでは、他のライブラリと同じように、JAXBAPIライブラリを依存関係として追加します。
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
上記のライブラリには、JAXBExceptionを含むJAXBAPIクラスのみが含まれています。 アプリケーションによっては、他のモジュールを含める必要がある場合があります。
また、JAXB APIの場合と同様に、Mavenアーティファクト名はJava9モジュール名とは異なる場合があることに注意してください。 MavenCentralにあります。
5. 結論
Java 9モジュールシステムには、アプリケーションサイズの縮小やパフォーマンスの向上など、多くの利点があります。
しかし、それはまた、いくつかの意図しない結果をもたらします。 Java 9にアップグレードするときは、アプリケーションが本当に必要とするモジュールを理解し、それらがクラスパスで使用可能であることを確認するための手順を実行することが重要です。