Support hiding some JRE packages from the plugin #697
-
Use Case: However, a challenge arises because the embedded javac JAR contains classes that overlap with those in JRE modules, such as java.compiler and jdk.compiler. In practice, the JRE's classes take precedence, so the plugin classloader prioritizes the JRE versions of these classes over those in our embedded javac. I'm looking for guidance on whether the OSGi platform provides a way to hide specific packages on the classpath from the plugin and allow it to use its own versions of overlapping classes. |
Beta Was this translation helpful? Give feedback.
Replies: 14 comments 20 replies
-
@testforstephen due to technical limitations you cannot "replace" any package from the |
Beta Was this translation helpful? Give feedback.
-
JustJ provides JREs that include javac: https://eclipse.dev/justj/?page=documentation I wonder if you can't just reuse that. As @laeubi suggests, I don't think your use case can be supported... |
Beta Was this translation helpful? Give feedback.
-
@merks @laeubi thanks for the response. Our project (JDT language server) uses javac API directly rather than invoking the javac.exe. The namespaces provided by the javac API are in the If there is no existing solution for it yet, would it be possible to use a custom classloader to prioritize loading our local version over the JRE’s? Or could we extend the MANIFEST.MF to support an attribute like |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
I think you should check out what the JDT project is doing to enable using javac for building the abstract syntax tree. Maybe they already solved this problem? |
Beta Was this translation helpful? Give feedback.
-
@laeubi I have configured the local javac.jar path in both However, during debugging the bundle, the Java runtime prioritizes the system module when finding javac api classes. I use the Java command line parameters I will take a look at
@merks JDT is using ECJ (Eclipse Compiler for Java) to build AST, the thing we're doing is to make JDT to support an alternative parser/compiler (e.g. javac). |
Beta Was this translation helpful? Give feedback.
-
I suggest you revisit what jdt is doing now because it’s doing exactly what you just stated. |
Beta Was this translation helpful? Give feedback.
-
@merks What you speak about is being done in subproject of jdt - jdt.ls (https://projects.eclipse.org/projects/eclipse.jdt.ls) and is not (yet!) part of main jdt. Also @testforstephen is one of the main drivers of that works and his request is in order to make this work easier. |
Beta Was this translation helpful? Give feedback.
-
@testforstephen Its a bit hard to guess what happens, maybe you can share a small example? In general the class-loading works like described here: https://docs.osgi.org/specification/osgi.core/8.0.0/framework.module.html#i3174728 and as mentioned above, the only package that can't be overridden is |
Beta Was this translation helpful? Give feedback.
-
I agree with @laeubi there must be something strange with your bundle. Like requiring the system bundle or Something like that will prevent you from loading the packages from your bundle's class path. |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
@merks @laeubi @tjwatson @akurtakov thank you all for the suggestions. Here are the reproducing steps:
As a result, it throws errors because javac api is loaded from A video to show what I observed. javac_class_loading.mp4 |
Beta Was this translation helpful? Give feedback.
-
@tjwatson @laeubi Thank you for the suggestions. Replacing |
Beta Was this translation helpful? Give feedback.
-
Following up on this, it seems like for this case, we have the following options to do things proper from a OSGi perspective:
But both have serious drawbacks that make them most likely not desired: So I'm wondering, for this niche use-case, is there a good strategy (such as a system bundle, or some lower-level OSGi hooks) to override how the dependency are being read by Equinox? If so, we could maybe try to just override how the MANIFEST.MF for org.eclipse.jdt.core is read, and just do the replacement we want dynamically, without needing upstream projects to change and thus keeping decent compatibility with those. |
Beta Was this translation helpful? Give feedback.
I agree with @laeubi there must be something strange with your bundle. Like requiring the system bundle or
org.eclipse.osgi
. Keep in mind that using require-bundle here will cause issues. For example, usingRequire-Bundle
fororg.eclipse.core.runtime
will pull in all oforg.eclipse.osgi
which in-turn exposes you to all the JDK packages because this horrible re-export:https://github.com/eclipse-platform/eclipse.platform/blob/6dd67323474b1b49d541bcd1e4ea8007ab2a36a4/runtime/bundles/org.eclipse.core.runtime/META-INF/MANIFEST.MF#L12C17-L12C87
Something like that will prevent you from loading the packages from your bundle's class path.