Classpath / classloader conflicts with other plugins in the buildscript

Greetings! So I’ve run into issues with classpath conflicts between my plugin and other plugins in the classpath.

What are the current gradleware plans towards isolating the classpath between plugins?

What is the best way currently to set up my own transitive dependencies that don’t conflict with other plugins on the classpath? Are there any good examples of simple ways to isolate my classpath?

One way would probably be to create a thread context classloader (with a parent last strategy) that only includes the classes you need. The actual libraries containing these classes could be retrieved through a custom configuration (exposed by your plugin) declared with the help of regular Gradle dependency management capabilities. I did something similar in one of my Gradle plugins.

What are the current gradleware plans towards isolating the classpath between plugins?

The work we are doing on plugins is outlined in this doc:

https://github.com/gradle/gradle/blob/master/design-docs/publishing-and-sharing-plugins.md

Note that the doc is still in progress so is less than comprehensive.

In short, lack of classpath isolation is a well known problem with no trivial solution. The new infrastructure we are building will address it.

Heya! I just wanted to follow up with this to make sure everyone knew what my solution became.

Ben, I tried your solution, but I had trouble getting the classpath configured properly, and additionally, the declared dependency of my plugin was bleeding into conflicts coming from other plugins. E.g., I couldn’t use a parent-first strategy because some of the crashes were coming from actually calling tasks on other plugins when I conflicted with their classes.

Ultimately, I went with a solution that dynamically invokes the main from a fat jar bundled inside my plugin. This has the effect of the gradle plugin classpath never having my artifact dependencies on the classpath AND my dynamically invoked class only uses its local classloader, thereby never interacting with the gradle one.

This solved my problem, but felt a bit outside the box. It does feel like something that probably could be automated outside of my plugin without changes to the gradle DSL. OTOH, I like having access to class definitions of other plugins’, as that allows me to react to, for example, the android-gradle plugin’s domain objects.

Greetings Luke,

Is there a way to follow the work effort you mentioned above?:

In short, lack of classpath isolation is a well known problem with no trivial solution.

The new infrastructure we are building will address it.

I searched issues.gradle.org for “plugin isolation” and “plugin classloader”. The closest thing I could find was GRADLE-723.

Best regards,

Ian

Hi Ian,

There currently isn’t, and the work that was going on has been put on hold in favour of other higher priority work. 

Only thing I can recommend is to peruse the Gradle release notes going forward.