redhat-developer / redhat-developer/vscode-java
Multi-Release JARs (MRJARs) pick the wrong class on higher Java versions
Nadie ha tomado este issue todavía.
- Lenguaje dominante
- TypeScript
- Estrellas
- 2.3k
- Forks
- 546
- Merge medio
- 20 h 1 min
- PR fusionados (30 d)
- 11
Descripción
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:
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Línea de trabajo
Reproduce el problema con el java-sandbox.zip enlazado, el Maybe for Java MRJAR y las toolchains de Java 11 y 17. Comienza con Java Project Explorer y el comando Java: Clean Java Language Server, y luego sigue cómo se selecciona la definición de la clase importada después de cambiar de versión. Se considera terminado cuando se muestra la clase MRJAR correspondiente a la versión actual de Java.
Escrito por el modelo de indexación a partir del texto del issue.
Evaluación
- Stack tecnológico
- java, typescript, vscode
- Área
- developer-experience, tooling
- Tipo de issue
- Error
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Estado de actividad
- Estancado
- Claridad
- Bastante claro
- Aptitud para principiantes
- 38/100