Groovy 与 Grape 和 AntBuilder 类加载器问题
我想使用 groovy 编写一个小 ftp 脚本,并发现这篇文章 http://www.hhhhq.org/blog/2009/05/01/ftp-using-groovy-and-ant/ 由于有几个依赖项,我想使用 Grape。所有依赖项均已解析并存在于缓存中。但我无法让 Ant 在其他库中找到可选任务。 它总是说
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
这是我的源代码
@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 不会在那里注入依赖项。 知道如何让它发挥作用吗?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您怀疑类加载器是问题的根源是正确的。正如您的代码已经揭示的那样,AntBuilder 是从 RootLoader 加载的,它无权访问 @Grab 注释加载的类。正如 GROOVY-3730 所示,Groovy 1.7 将解决这个问题。
但是,您可以直接使用 groovy.grape.Grape.grab(Map dependency) 方法来解决您的问题,在该方法中您可以设置用于加载依赖项的特定类加载器:
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:或者只是简单地使用
可以找到更多信息:http://groovy.codehaus.org/Grape
Or just simply use
Further info can be found: http://groovy.codehaus.org/Grape