-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce Plexus ClassWorld for more control over the classloaders #13845
Conversation
…here should be different configuration for this instance
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #13845 +/- ##
============================================
- Coverage 61.75% 57.56% -4.19%
+ Complexity 207 197 -10
============================================
Files 2436 2578 +142
Lines 133233 142305 +9072
Branches 20636 22102 +1466
============================================
- Hits 82274 81914 -360
- Misses 44911 53899 +8988
- Partials 6048 6492 +444
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are jar files included intentionally? It will add almost 40MB to the repo
It can be replaced with any jar, but that means it will be a customized jar. What I can do is remove all the unused (untested) classes from this jar. Or do you have something else in mind? |
Question about the Jars: If we change the test to be an integration test and we use failsafe instead of surfire... would we be able to consume the actual jar from the plugins instead of the ones we include in resources? |
I guess the question is: can we let Maven download the jars instead? In this case the jars are test-resources and not dependencies, so I wouldn't abuse test-scoped dependencies. What we can do is to make use of https://maven.apache.org/plugins/maven-dependency-plugin/copy-mojo.html to copy the dependencies to the preferred location. Let me prepare that. (in this case it is still a unittest, so no benefits when using failsafe) |
ClassLoader pinotLoader = _classWorld.getClassRealm("pinot"); | ||
|
||
// All exported packages | ||
Stream.of("org.apache.pinot.spi.accounting", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This list is an assumption. Plugins should only make use of classes in these packages, which is any inside the pinot-spi module. Any other pinot-packages will not be accessible.
@@ -41,11 +47,16 @@ public class PluginManager { | |||
|
|||
public static final String PLUGINS_DIR_PROPERTY_NAME = "plugins.dir"; | |||
public static final String PLUGINS_INCLUDE_PROPERTY_NAME = "plugins.include"; | |||
public static final String PLUGINS_LOADER_LEGACY_PROPERTY_NAME = "pinot.plugins.loader.legacy"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've introduced a system property to fall back to the original behavior. I can imagine that some plugins rely on internal pinot-classes, which will now fail.
Could you please update the PR description with some context to help people understand the intention of the PR? |
pinot-spi/pom.xml
Outdated
<execution> | ||
<id>copy-pinot-plugins</id> | ||
<phase>process-test-resources</phase> | ||
<goals> | ||
<goal>copy</goal> | ||
</goals> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I think this is a good idea but probably devs are not going to understand on a first read why this plugin is necessary.
Can you add a comment here saying that PluginManagerTest requires these resources and we decided to copy them at build time?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, this could use an extra comment
PluginManagerTest test is failing right now with:
|
…st-classes/plugins
…ot you'll have "unlimited" mode, all classes will be looked up in the pinot-realm first.
@@ -41,10 +51,18 @@ public class PluginManager { | |||
|
|||
public static final String PLUGINS_DIR_PROPERTY_NAME = "plugins.dir"; | |||
public static final String PLUGINS_INCLUDE_PROPERTY_NAME = "plugins.include"; | |||
public static final String PLUGINS_LOADER_LEGACY_PROPERTY_NAME = "pinot.plugins.loader.legacy"; | |||
public static final String PLUGINS_LOADER_LEGACY_DEFAULT = "false"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be true for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably we should rename the property to be something like pinot.plugins.loader=plexus
. In case the property is not defined, we use the legacy mode. In the future we will be able to change the default to plexus.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we make legacy the default, I wonder if anyone dares to switch to plexus classworld, even though classloader issues keep happening. Instead I propose to make plexus classworlds behave more like its current behavior. i.e. having access to all classes (like now) but loading them in the expected order. In other words: make them unlimited. The switch to limited as default is smaller.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are used to use flags to enable new features to be sure we do not affect deployments where the flag is not set. I'm sure StarTree will use the new system in their deployments (after testing it for a while), so I'm sure it is going to be used.
I'm going to close this PR because Robert has been focused on #13907, which also includes the new plugin layout and simplifies the logic here |
There is a known and longstanding issue with pinot plugins and class colissions. The problem lies in not being able to control where classes should be coming from. In the end it is all about classloaders.
The JRE recognized this issue and came with the Java Platform Module System, but that comes with other requirements.
Apache Maven also has the concept of plugins and has been using Plexus Classworld to solve that issue (see https://maven.apache.org/guides/mini/guide-maven-classloading.html)
With Plexus Classworld it is possible to define the order of classloaders, scope the exported and imported packages, etc. , see https://codehaus-plexus.github.io/plexus-classworlds/ .
This PR will introduce a library that has proven itself. Even if discover other classloading issues, it will possible to configure Plexus Classworld to solve that.