redhat-developer / redhat-developer/vscode-java
Multi-Release JARs (MRJARs) pick the wrong class on higher Java versions
まだ誰も着手していません。
- 主要言語
- TypeScript
- スター
- 2.3k
- フォーク
- 546
- 平均マージ
- 20時間 1分
- マージ済み PR(30日)
- 11
説明
Libraries in the classpath with a Multi-Release structure work fine when using the lowest allowed Java version. However, when using a higher version that provides a replacement class, VSCode loads the lower version instead of the replacement. Another interesting thing is that when looking at the library on the Java Project Explorer using a higher Java version, classes with a replacement show duplicates, but they all switch back to the lowest when opened.
Environment
- Operating System: Windows 11 - 22H2 (build 22621.2283)
- JDK version: v20.0.2 (Gradle Java Toolchain for 11 and 17)
- Visual Studio Code version: v1.82.2
- Java extension version: v1.22.1
Steps To Reproduce
- Add a Multi-Release JAR dependency to a project.
- For these steps, I'm using Maybe for Java, which is a library of my authoring. This way, I know the
Eitherinterface has a replacement for Java 17, which makes the interface sealed, plus it uses record classes for the implementations. - This means that on Java 11, you could make any class implement
Either. But on Java 17, trying to implementEithershould show a compilation error.
- For these steps, I'm using Maybe for Java, which is a library of my authoring. This way, I know the
- Make sure to use the lowest allowed Java version for the library (e.g., Java 11)
- Use the Java Project Explorer to ensure the MRJAR lib has the
META-INF/versionsfolder with replacement classes - Import a class with replacement (e.g.,
import io.github.joselion.maybe.utils.Either;) - Go to the definition of the imported class. It should show its lowest version (e.g., interface without sealed keyword and no records)
- Switch to a higher Java version (e.g., Java 17)
- Using Gradle and the Java Toolchain can be useful
- You may need to run the
Java: Clean Java Language Servercommand
- Use the Java Project Explorer to verify the
META-INFdirectory does not containversionsanymore - Go to the definition of the imported class again. It still shows the lowest version (e.g., it should show a sealed interface and records instead)
Sample project: java-sandbox.zip
Logs: Nothing is logged during the process
Current Result
MRJAR references the lowest version class when using a higher Java version
Expected Result
MRJAR references should use the matching class based on the current Java version.
Additional Information
I'm willing to help with a PR if someone can point me in the right direction. Knowing where and how this should be handled will be of great help 🙂
I'm also adding some screenshots of the Java Project Explorer with an MRJAR dependency expanded.
With Java 11:
With Java 17:
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
リンクされている java-sandbox.zip、Maybe for Java MRJAR、および Java toolchain 11 と 17 で問題を再現します。まず Java Project Explorer と Java: Clean Java Language Server コマンドから始め、バージョンを切り替えた後にインポートされたクラス定義がどのように選択されるかを追跡します。現在の Java バージョンに対応する MRJAR クラスが表示されれば完了です。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- java, typescript, vscode
- 領域
- developer-experience, tooling
- issue の種類
- バグ
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 活発さ
- 停滞
- 明瞭さ
- おおむね明確
- 初心者へのやさしさ
- 38/100