Gradle classloading

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Gradle classloading

hans_d
Administrator
Hi,

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  
AntBuilder.

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.

- Hans

--
Hans Dockter
Gradle Project lead
http://www.gradle.org





---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: Gradle classloading

Ittay Dror
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.

Ittay
hdockter wrote
Hi,

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  
AntBuilder.

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.

- Hans

--
Hans Dockter
Gradle Project lead
http://www.gradle.org





---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email