Eclipseで Mavenプロジェクト (ブランチplatform-bom_brussels-sr7)で開発しています。最近、プロジェクトのJava Build PathをJDK 10に切り替えようとしたときに、Eclipseビルドでjavax.xml.xpath.XPath
、org.w3c.dom.Document
、org.xml.sax.SAXException
などのクラスが見つかりません。主にMaven依存関係xml-apis-1.4.01
から影響を受けるのは、XML関連クラスのみです。
EclipseからMavenビルドを試行しても、エラーなしで機能します。欠落していると思われるクラスの1つでCtrlキーを押しながら左クリックすると、クラスが検出され、Eclipseエディターで開かれます。 Eclipseビルドのみが影響を受けるようです。
いくつか試してみましたが、何も助けませんでした。私は試した:
Java 1.8から移行されるプロジェクトには、まだmodule-info.Java
がないと想定しています。これは、「名前のないモジュール」でコードをコンパイルしていることを意味します。
名前のないモジュールのコードは、監視可能なすべての名前の付いたモジュールと名前のないモジュールを「読み取り」ます。特に、JREシステムライブラリからモジュール「Java.xml」を読み取ります。このモジュールは、Java.xml.xpath
のようなパッケージをエクスポートします。
さらに、クラスパスにxml-apis.Java
があり、同じ名前の別のパッケージセット(Java.xml.xpath
とその友人)を提供します。これらは、独自のコードのように、名前のないモジュールに関連付けられていると言われています。
この状況は、- JLS§7.4. (最後の段落)で定義されている「一意の可視性」の要件に違反しています。特に、すべての修飾された型名Q.Id( JSL§6.5.5.2 )では、接頭辞Qが一意に表示されるパッケージであることが必要です(簡単にするために、ネストされた型の場合は無視します)。エルゴ:プログラムは違法であり、コンパイラーによって拒否される必要があります。
これにより、1つの質問と2つの解決策が残ります。
(1)質問:javacがプログラムを受け入れるのはなぜですか?
(2)解決策:module-info.Java
をプロジェクトに追加する場合、requiresによってプロジェクトが読み込むモジュールを制御できます。requires Java.xml;
またはrequires xml.apis;
(ここで、 xml.apis」は、「xml-apis-1.4.01.jar」の自動モジュール名です。
(3)解決策:プロジェクトをモジュールに変換する前に、監視可能なモジュールのセットからJava.xml
を除外することにより、競合を回避できます。コマンドラインでは、これは--limit-modules
を使用して実行されます。 Eclipseで同等のものは "Modularity Details"ダイアログ です。 JDT 4.8 New&Noteworthy (Contentsタブを探してください)も参照してください。 Java.xml
は、他の多くのデフォルトで監視可能なモジュールを介して暗黙的に必要とされるため、Java.base
を除くすべてを右(「明示的に含まれるモジュール」)から左(「使用可能なモジュール")(およびプロジェクトに必要なモジュールを選択的に再追加します)。
PS:Eclipseはまだ「解決できない」の代わりに理想的なエラーメッセージを提供していません。実際には、パッケージjavax.xml.xpathは複数のモジュールからアクセスできます:javax.xml、<unnamed>。
PPS:また奇妙なことに、JREとクラスパス上のjarの間で順序を変更すると(そのような順序はjavacやJEP 261でサポートされる概念ではない)、コンパイラの動作が変わるのはなぜですか。
編集:
これは Eclipse Bug 536928 として報告されているようです。たぶん誰もがそれに投票することになれば、彼らは優先順位を上げるでしょう。
Eclipse 4.8.0とJDK 10で非常によく似たものを見てきました。
import org.w3c.dom.Element;
eclipseでのコンパイルに失敗していました:The import org.w3c.dom.Element cannot be resolved
それでも、押す F3 (オープン宣言)そのインポートで、Eclipseはインターフェース定義を開くことができました-この場合はxml-apis-1.4.01.jar
の下です。
一方、Maven directからのビルドは正常に機能していました。
この場合、修正はpom.xml
からこの依存関係を削除することでした:
<dependency>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
<version>1.4.01</version>
</dependency>
その後、Eclipseのコンパイルエラーは解消されました。以下 F3 再びElement
インターフェイスが表示されました-現在はJava.xml
モジュールの下、プロジェクトの下のJREシステムライブラリの下にあります。また、Mavenビルドは正常なままでした。
これは、JDKモジュールと依存する.jarファイルの両方で見つかったクラスを解決するEclipseの問題のように感じられます。
興味深いことに、今回はEclipse 4.9.0とJDK 11の下の別の環境では、xml-apis:1.4.01
依存関係の有無にかかわらずすべて問題ありません。
jdk 9+は、プロジェクトジグソーに関連する変更をもたらしました。 JDKはさまざまなモジュールに分割され、javaee、jaxb、xml関連の一部のモジュールはデフォルトでロードされなくなりました。これらをjreクラスパスにあることを期待するのではなく、mavenビルドに直接追加する必要があります。こちらをご覧ください SO question
これは回避策ですが、私の経験からは、「Java Build Path」、「Order and Export」タブに移動し、「Maven Dependencies」を下部に送信することで解決できます(したがって、 「JREシステムライブラリ」)。