本文介绍了Groovy with Grape 和 AntBuilder 类加载器问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将 groovy 用于一个小的 ftp 脚本并找到了这篇文章 http://www.hhhhq.org/blog/2009/05/01/ftp-using-groovy-and-ant/由于有几个依赖项,我想使用 Grape.所有依赖项都已解析并存在于缓存中.但是我无法让 Ant 在其他库中找到可选任务.它总是说

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 版本:1.6.5 JVM:1.6.0_15

Groovy Version: 1.6.5 JVM: 1.6.0_15

这是我的源代码

@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()

正如你所看到的,我怀疑类加载器是问题所在,似乎Grape 不会在那里注入依赖项.知道如何让它工作吗?

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

推荐答案

您怀疑类加载器是问题的根源是正确的.正如您的代码已经显示的那样,AntBuilder 是从 RootLoader 加载的,它无权访问由 @Grab 批注加载的类.正如 GROOVY-3730 所示,Groovy 1.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.

但是,您可以直接使用 groovy.grape.Grape.grab(Map dependency) 方法来解决您的问题,您可以在该方法中设置一个特定的类加载器,用于加载依赖项:

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)

这篇关于Groovy with Grape 和 AntBuilder 类加载器问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-12 07:52