Groovy with Grape and AntBuilder classloader problem
Asked Answered
T

2

7

I wanted to use groovy for a little ftp script and found this post http://www.hhhhq.org/blog/2009/05/01/ftp-using-groovy-and-ant/ Since there were several dependencies I wanted to use Grape. All dependencies are resolved and present in the cache. But I can't get Ant to find the optional tasks in the other libs. It always says

Caught: : Problem: failed to create task or type ftp
Cause: the class org.apache.tools.ant.taskdefs.optional.net.FTP was not found.
        This looks like one of Ant's optional components.
Action: Check that the appropriate optional JAR exists in
        -ANT_HOME\lib
        -the IDE Ant configuration dialogs

Do not panic, this is a common problem.
The commonest cause is a missing JAR.

This is not a bug; it is a configuration problem

        at GrabTest.runMe(GrabTest.groovy:15)
        at GrabTest.run(GrabTest.groovy:26)

Groovy Version: 1.6.5 JVM: 1.6.0_15

Here is my source code

@Grab(group='ant', module='ant', version='[1.6.5,)')
@Grab(group='ant', module='ant-nodeps', version='[1.0,)')
@Grab(group='ant', module='ant-apache-oro', version='[1.0,)') 
@Grab(group='ant', module='ant-commons-net', version='[1.0,)') 
@Grab(group='apache-oro', module='jakarta-oro', version='[2.0.8,)')
@Grab(group='commons-net', module='commons-net', version='[1.4,)')
def runMe() {
    // works
    println getClass().getClassLoader().loadClass("org.apache.tools.ant.taskdefs.optional.net.FTP")

    def ant = new AntBuilder()

    println getClass().getClassLoader() //groovy.lang.GroovyClassLoader$InnerLoader
    println ant.getClass().getClassLoader() //org.codehaus.groovy.tools.RootLoader
    ant.ftp( server:"ftp.foo.com",
            userid:"user",
            password:"passwd",
            passive:"yes",
            verbose:"yes",
            remotedir:"/pub/incoming",
            binary:"yes" ) {
                fileset( dir:"." ) { include( name:"**/*.gz" ) }
            }
}

runMe()

As you can see I suspect the classloader of being the problem, it seems that Grape doesn't inject the dependencies there. Any idea of how I can get it to work?

Travis answered 29/10, 2009 at 1:15 Comment(0)
S
7

You're right suspecting the classloader to be the root of the problem. As your code already reveals, the AntBuilder is loaded from the RootLoader, that doesn't have access to the classes loaded by the @Grab annotation. As GROOVY-3730 shows, Groovy 1.7 is going to address this problem.

However, you can solve your problem by directly using the groovy.grape.Grape.grab(Map dependency) method, in which you can set a specific classloader that should be used to load the dependencies:

import groovy.grape.Grape;

Grape.grab(group:'ant', module:'ant', version:'1.6.5', classLoader:this.class.classLoader.rootLoader)
Grape.grab(group:'ant', module:'ant-nodeps', version:'1.6.5', classLoader:this.class.classLoader.rootLoader)
Grape.grab(group:'ant', module:'ant-apache-oro', version:'1.6.5', classLoader:this.class.classLoader.rootLoader)
Grape.grab(group:'ant', module:'ant-commons-net', version:'1.6.5', classLoader:this.class.classLoader.rootLoader)
Grape.grab(group:'commons-net', module:'commons-net', version:'1.4.1', classLoader:this.class.classLoader.rootLoader)
Grape.grab(group:'oro', module:'oro', version:'2.0.8', classLoader:this.class.classLoader.rootLoader)
Syndesmosis answered 29/10, 2009 at 9:4 Comment(2)
Hi Chris, I tried your solution and I get this error: Caught: groovy.lang.MissingMethodException: No signature of method: static groovy.lang.Grab.grab() is applicable for argument types: (java.util.LinkedHashMap) values: [[group:org.codenarc, module:CodeNarc, version:0.11, classLoader:org.codehaus.groovy.tools.RootLoader@addbf1]] Possible solutions: grep(java.lang.Object), wait(), dump(), any(), getAt(java.lang.String), wait(long) at CodeNarcTest.run(CodeNarcTest.groovy:3). Any ideas? I am using groovy version 1.7.6Thanhthank
Hi Steven, it seems you're using the groovy.lang.Grab annotation type instead of the groovy.grape.Grape class. Can you check this, please?Syndesmosis
D
0

Or just simply use

@GrabConfig(systemClassLoader=true)

Further info can be found: http://groovy.codehaus.org/Grape

Dairy answered 26/6, 2013 at 19:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.