Java 9でのJAXBExceptionのNoClassDefFoundErrorの処理
1. 前書き
Java 9へのアップグレードを試みた人は、以前のバージョンのJavaで機能していたコードをコンパイルするときに、ある種のNoClassDefFoundError を経験した可能性があります。
この記事では、不足している一般的なクラスJAXBExceptionと、それを解決するためのさまざまな方法について説明します。 ここで提供されるソリューションは、Java 9へのアップグレード時に欠落する可能性のあるすべてのクラスに一般的に適用可能です。
2. Java 9がJAXBExceptionを見つけられないのはなぜですか?
Java 9で最も議論されている機能の1つは、モジュールシステムです。 The goal of the Java 9 module system is to break apart the core JVM classes and related projects into stand-alone modules。 これにより、実行に最低限必要なクラスのみを含めることで、フットプリントの小さいアプリケーションを作成できます。
欠点は、デフォルトではクラスパスで多くのクラスが利用できなくなることです。 この場合、クラスJAXBExceptionは、java.xml.bindという名前の新しいJavaEEモジュールの1つにあります。 このモジュールはコアJavaランタイムでは必要ないため、デフォルトではクラスパスでは使用できません。
JAXBExceptionを使用するアプリケーションを実行しようとすると、次のようになります。
NoClassDefFoundError: javax/xml/bind/JAXBException
このwe must include the java.xml.bindmoduleを回避するには。 以下で説明するように、これを実現するには複数の方法があります。
3. 短期的な解決策
JAXB APIクラスがアプリケーションで使用可能であることを確認する最も簡単な方法は、use the –add-modules command line argumentを追加することです。
--add-modules java.xml.bind
ただし、これはいくつかの理由で良い解決策ではないかもしれません。
まず、–add-modules argumentもJava9の新機能です。 Javaの複数のバージョンで実行する必要があるアプリケーションの場合、これにはいくつかの課題があります。 アプリケーションが実行されるJavaバージョンごとに1つずつ、複数のビルドファイルのセットを維持する必要があります。
これを回避するために、古いJavaコンパイラの-XX:+IgnoreUnrecognizedVMOptionsコマンドライン引数を使用することもできます。
ただし、これは、タイプミスやスペルミスのある議論が私たちの注意を引くことがないことを意味します。 たとえば、最小または最大のヒープサイズを設定し、引数名を誤って入力しようとしても、警告は表示されません。 アプリケーションは引き続き起動しますが、予想とは異なる構成で実行されます。
次に、–add-modules optionは将来のJavaリリースで非推奨になります。 つまり、新しいバージョンのJavaにアップグレードした後のある時点で、不明なコマンドライン引数を使用するという同じ問題に直面し、問題に再度対処する必要があります。
4. 長期的な解決策
Javaのさまざまなバージョンで機能し、将来のリリースで中断しない、より良いアプローチがあります。
解決策は、utilize a dependency management tool such as Mavenです。 このアプローチでは、他のライブラリと同様に、JAXB APIライブラリを依存関係として追加します。
javax.xml.bind
jaxb-api
2.3.0
上記のライブラリには、JAXBExceptionを含むJAXBAPIクラスのみが含まれています。 アプリケーションによっては、他のモジュールを含める必要がある場合があります。
また、JAXB APIの場合と同様に、Maven artifact names may be different than the Java 9 module nameにも注意してください。 Maven Centralにあります。
5. 結論
Java 9モジュールシステムには、アプリケーションサイズの縮小やパフォーマンスの向上など、多くの利点があります。
ただし、意図しない結果も生じます。 Java 9にアップグレードする場合、アプリケーションが本当に必要とするモジュールを理解し、それらがクラスパスで使用可能であることを確認する手順を実行することが重要です。