我想从Gradle构建脚本运行一个groovy命令行脚本。
我在Gradle脚本中使用此代码:
def groovyShell = new GroovyShell();
groovyShell.run(file('script.groovy'), ['arg1', 'arg2'] as String[])
在我的Groovy脚本(script.groovy)使用CliBuilder类之前,一切正常。然后我得到以下异常:
org.codehaus.groovy.runtime.InvokerInvocationException:java.lang.NoClassDefFoundError:org / apache / commons / cli / ParseException ... 引起:java.lang.ClassNotFoundException:org.apache.commons.cli.ParseException
我发现很多人有类似的问题和错误,但“解决方案”很难从我读过的众多帖子中提取出来。很多人建议将commons-cli jar放在类路径上,但对GroovyShell这样做对我来说并不是很明显。另外,我已经在script.groovy中为我所需的库声明了@Grapes和@Grab,所以它应该拥有它所需的一切。
答案 0 :(得分:8)
感谢this unaccepted SO answer,我终于找到了我需要做的事情:
//define our own configuration
configurations{
addToClassLoader
}
//List the dependencies that our shell scripts will require in their classLoader:
dependencies {
addToClassLoader group: 'commons-cli', name: 'commons-cli', version: '1.2'
}
//Now add those dependencies to the root classLoader:
URLClassLoader loader = GroovyObject.class.classLoader
configurations.addToClassLoader.each {File file ->
loader.addURL(file.toURL())
}
//And now no more exception when I run this:
def groovyShell = new GroovyShell();
groovyShell.run(file('script.groovy'), ['arg1', 'arg2'] as String[])
您可以找到有关classLoaders的更多详细信息以及此解决方案的工作原理in this forum post。
快乐的脚本!
(在您回答我自己的问题之前,read this)
答案 1 :(得分:2)
执行此操作的替代方法如下:
buildScript {
repositories { mavenCentral() }
dependencies {
classpath "commons-cli:commons-cli:1.2"
}
}
def groovyShell = new GroovyShell()
....
这会将commons-cli依赖于buildscript的类路径而不是要构建的项目的类路径。