I'm thinking about how to improve the Gradle classloading.
In Gradle we deal with two classpaths. One is the classpath for
running Gradle, the other is the classpath for compiling and
executing our build scripts. The first is a subset of the second as
we wan to be able to access or instantiate any Gradle class in our
build scripts and do something with it. The build script classpath
has additional elements. The tools.jar for example or the
dependencies you can define in your settings.gradle file. This is one
area where we have problems. Let's look at some examples:
Ivy is in the gradle classpath. Now you want to add Jsch via the
settings.gradle. JSch is needed by Ivy if you want to use ssh
uploading. If I declare a build script classloader with the gradle
classloader as its parent, I have the problem that Ivy is loaded by
the Gradle classloader and therefore does not look for JSch in the
child classloader, but throws a ClassNotFoundException. The same is
true for optional Ant tasks jar I add via the settings.gradle.
One way I've tried to solve the problem is to declare a build script
classloader which has all the jars of the Gradle classloader plus the
additional ones. Its parent is the parent of the system classloader.
Then I get exceptions because the Groovy classes which are already
loaded are in conflict with the Groovy which is now contained in a
different classloader. I have also tried to create a bootstrap
classloader which contains only Groovy and which is the parent of the
other classloaders. Bu Groovy has a dependency on Ant as we use the
One fix to this problem would be to have only one classloader where
we add the additional elements of settings.gradle at runtime.
A really clean solution would be to have strict isolation like you
could achieve with OSGi. The build script classpath has a dependency
on the gradle class container. But the gradle class container only
exposes Gradle, Groovy and Ivy. All the other jars needed by Gradle,
Groovy and Ivy are hidden. Additionally the build script classloader
should solve the child/parent problem described above.
I'm looking forward to your feedback.
Gradle Project lead
To unsubscribe from this list, please visit:
I vote for the single classloader. It is easier to understand and I think other classloading solutions are prone to ClassNotFound issues. KISS works for me here.
|Free forum by Nabble||Edit this page|