Philip Crotwell wrote:
Hi

I am trying to use a groovy class in my build.gradle that is defined
in a separate file. Because I want all my build scripts to not require
external configuration (like classpath)

Why does it need to be a separate file? I'm curious, because we are making some improvements to build script classpath handling in Gradle 0.7, and I would like to understand what your use case is, and whether we would solve it with the 0.7 changes.

 I am trying to dynamically
load the groovy code from within the gradle buildfile. I found two
items that seem to help with this:

Another option you have is to place the file under buildSrc/src/main/groovy. It will then be automatically compiled and included in the build script classpath.

http://groovy.codehaus.org/Influencing+class+loading+at+runtime
http://www.nabble.com/run-main%2C-package-all-libs%2C-run-easyb-td22395236.html#a22410033

Both say that you should add the URL to the root GroovyClassLoader.
However, when I try this in my build.gradle:

createTask('play') {
    println 'rootLoader: '+this.class.classLoader.rootLoader
    def classLoader = this.class.classLoader
    while (classLoader != null) {
        println 'parent loader '+classLoader.class+'  '+classLoader
        classLoader = classLoader.parent
    }
}

I get this:
crotwell$ gradle play
:TauP:play
rootLoader: null
parent loader class java.net.URLClassLoader  java.net.urlclassloa...@c9e1cc
parent loader class java.net.URLClassLoader  java.net.urlclassloa...@cd8669
parent loader class java.net.URLClassLoader  java.net.urlclassloa...@337838
parent loader class sun.misc.Launcher$ExtClassLoader
sun.misc.launcher$extclassloa...@cc7ad6

BUILD SUCCESSFUL

and so it would seem that there is no GroovyClassLoader in the class
loader hierarchy that you get from this.class.classLoader. That seems
strange as I thought we were using groovy inside of a Task.


In this case, 'this' refers to the build script, rather than the task. The build script is compiled into the cache in the .gradle directory, and then loaded using a URLClassLoader, rather than a GroovyClassLoader (I wonder if we should use a GroovyClassLoader, instead).

I found another post that just constructed a GroovyClassLoader and used it,
http://www.mail-archive.com/[email protected]/msg01296.html
Which more or less works. If I create a GroovyClassLoader myself, I
can load my class, but it of course is missing all the gradle stuff so
I can't do something like:
import org.gradle.api.artifacts.report.IvyDependency

So, what is the correct way to load groovy code from a separate file
into a gradle build, and still have access to the gradle classes?


There's no one way to do this. GroovyClassLoader is a good option. GroovyShell is another option if you want to execute a script.

Either way, you need to construct the GroovyClassLoader or GroovyShell with the build script's ClassLoader as its parent ClassLoader. This way any classes loaded by the ClassLoader will be able to see all classes visible to the build script:

def classLoader = new GroovyClassLoader(this.class.classLoader)
classLoader.addClasspath(... some path ...) // or addURL()
def myObject = classLoader.parseClass(new File(... some groovy file ...)).newInstance()


Adam


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

   http://xircles.codehaus.org/manage_email


Reply via email to