Groovy with Grape and AntBuilder classloader problem

有些话、适合烂在心里 提交于 2019-12-04 11:44:16

问题


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?


回答1:


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)



回答2:


Or just simply use

@GrabConfig(systemClassLoader=true)

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



来源:https://stackoverflow.com/questions/1641116/groovy-with-grape-and-antbuilder-classloader-problem

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!