使用GroovyShell从Gradle运行Groovy脚本:线程"main"中的异常java.lang.NoClassDefFoundError:org/apache/commons/cli/ParseException

Tay*_*tay 6 groovy gradle

我想从我的Gradle构建脚本运行一个groovy命令行脚本.

我在Gradle脚本中使用此代码:

def groovyShell = new GroovyShell();
groovyShell.run(file('script.groovy'), ['arg1', 'arg2'] as String[])
Run Code Online (Sandbox Code Playgroud)

在我的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,所以它应该拥有它所需的一切.

Tay*_*tay 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[])
Run Code Online (Sandbox Code Playgroud)

您可以在此论坛帖子中找到有关classLoaders的更多详细信息以及此解决方案的工作原理.

快乐的脚本!

(在您回答我自己的问题之前,请先阅读此内容)