6

我想从我的 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,所以它应该有它需要的一切。

4

2 回答 2

8

感谢这个不被接受的 SO 答案,我终于找到了我需要做的事情:

//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 以及此解决方案为何有效的更多详细信息。

快乐的脚本!

(在您投票反对我回答我自己的问题之前,请阅读此内容

于 2012-12-07T12:28:30.927 回答
2

执行此操作的替代方法如下:

buildScript {
  repositories { mavenCentral() }
  dependencies {
    classpath "commons-cli:commons-cli:1.2"
  }
}

def groovyShell = new GroovyShell()
....

这会将 commons-cli 依赖项放在构建脚本的类路径上,而不是放在要构建的项目的类路径上。

于 2012-12-07T12:49:59.677 回答