使用命令行参数静态编译 groovy 脚本
Compile groovy script statically with command line arguments
我正在尝试静态编译 groovy 脚本以加快其执行速度,但如果使用命令行参数,我将无法使其正常工作。我的实际脚本要长得多,但我用于此问题的单行脚本完美地重现了我的错误。
使用以下脚本 (test.groovy)
println(args.length)
这可以通过java命令java -cp .;%GROOVY_HOME%\lib\* test
使用命令groovyc test.groovy
和运行编译,并且将简单地打印使用的命令行参数的数量。
现在,如果我提供脚本 (config.groovy)
withConfig(configuration) {
ast(groovy.transform.CompileStatic)
}
并用groovyc -configscript config.groovy test.groovy
编译,我得到一个错误
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
testing.groovy: 1: [Static type checking] - The variable [args] is undeclared.
@ line 1, column 9.
println(args.length)
^
1 error
此错误仅在我尝试静态编译时发生。我可以通过将脚本包装在 class 中并将我的代码放入 main 方法中(当然,这是编译器对脚本所做的)来让它工作,但是当我尝试只使用脚本(这是我喜欢做的)。由于某种原因,静态编译时变量 args 是未知的。我试过 this.args
但仍然收到错误。如果我尝试为 args (String[] args
) 声明类型,它不再接收命令行参数。
当脚本以这种方式静态编译时,是否仍然可以获取命令行参数?
我在 Windows 7 和 Java 8.
上使用 Groovy 版本 2.4.10
执行 Groovy class 和 运行 简单脚本有区别。编译器简单地将脚本包装在 main 方法中是不正确的,脚本的主体将被复制到 run
方法中。
示例:
println(args.length)
将转换为
import org.codehaus.groovy.runtime.InvokerHelper
class Main extends Script {
def run() {
println(args.length)
}
static void main(String[] args) {
InvokerHelper.runScript(Main, args)
}
}
由于是动态类型,因此可以正常编译。
现在,如果我们向 class 添加 @CompileStatic
注释,我们将得到未声明变量的错误。
因此,您必须将代码包装在 class 中才能使用静态编译。
您可以在 documentation 中阅读有关脚本与 classes 的更多信息。
脚本通过绑定对象的动态评估工作。如果要使用静态编译,则需要使用显式形式,将 test.groovy 脚本更改为以下内容:
String[] args = (String[])binding.getVariable('args')
println args.length
使用您已经提供的配置脚本,您可以获得静态编译脚本。我以这种方式测试了 运行:
groovyc --configscript config.groovy test.groovy
java -cp .;%GROOVY_HOME%\lib\groovy-2.5.3.jar test 1 2 3
这会打印 3
.
如果你不想修改test.groovy,你可以创建一个新的基础class:
import groovy.transform.CompileStatic
@CompileStatic
abstract class StaticBase extends Script {
StaticBase() {
}
StaticBase(Binding binding) {
super(binding)
}
String[] getArgs() {
(String[]) getBinding().getVariable("args")
}
}
由于基础 class 有一个方法 getArgs
,那么当 test.groovy 引用 args 时,静态编译器会调用对该方法的调用。
groovyc --configscript config.groovy -b StaticBase test.groovy
java -cp .;%GROOVY_HOME%\lib\groovy-2.5.3.jar test 1 2
test.class中的代码有一个运行方法,其代码代表this.println(this.getArgs().length)
我正在尝试静态编译 groovy 脚本以加快其执行速度,但如果使用命令行参数,我将无法使其正常工作。我的实际脚本要长得多,但我用于此问题的单行脚本完美地重现了我的错误。
使用以下脚本 (test.groovy)
println(args.length)
这可以通过java命令java -cp .;%GROOVY_HOME%\lib\* test
使用命令groovyc test.groovy
和运行编译,并且将简单地打印使用的命令行参数的数量。
现在,如果我提供脚本 (config.groovy)
withConfig(configuration) {
ast(groovy.transform.CompileStatic)
}
并用groovyc -configscript config.groovy test.groovy
编译,我得到一个错误
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
testing.groovy: 1: [Static type checking] - The variable [args] is undeclared.
@ line 1, column 9.
println(args.length)
^
1 error
此错误仅在我尝试静态编译时发生。我可以通过将脚本包装在 class 中并将我的代码放入 main 方法中(当然,这是编译器对脚本所做的)来让它工作,但是当我尝试只使用脚本(这是我喜欢做的)。由于某种原因,静态编译时变量 args 是未知的。我试过 this.args
但仍然收到错误。如果我尝试为 args (String[] args
) 声明类型,它不再接收命令行参数。
当脚本以这种方式静态编译时,是否仍然可以获取命令行参数?
我在 Windows 7 和 Java 8.
上使用 Groovy 版本 2.4.10执行 Groovy class 和 运行 简单脚本有区别。编译器简单地将脚本包装在 main 方法中是不正确的,脚本的主体将被复制到 run
方法中。
示例:
println(args.length)
将转换为
import org.codehaus.groovy.runtime.InvokerHelper
class Main extends Script {
def run() {
println(args.length)
}
static void main(String[] args) {
InvokerHelper.runScript(Main, args)
}
}
由于是动态类型,因此可以正常编译。
现在,如果我们向 class 添加 @CompileStatic
注释,我们将得到未声明变量的错误。
因此,您必须将代码包装在 class 中才能使用静态编译。
您可以在 documentation 中阅读有关脚本与 classes 的更多信息。
脚本通过绑定对象的动态评估工作。如果要使用静态编译,则需要使用显式形式,将 test.groovy 脚本更改为以下内容:
String[] args = (String[])binding.getVariable('args')
println args.length
使用您已经提供的配置脚本,您可以获得静态编译脚本。我以这种方式测试了 运行:
groovyc --configscript config.groovy test.groovy
java -cp .;%GROOVY_HOME%\lib\groovy-2.5.3.jar test 1 2 3
这会打印 3
.
如果你不想修改test.groovy,你可以创建一个新的基础class:
import groovy.transform.CompileStatic
@CompileStatic
abstract class StaticBase extends Script {
StaticBase() {
}
StaticBase(Binding binding) {
super(binding)
}
String[] getArgs() {
(String[]) getBinding().getVariable("args")
}
}
由于基础 class 有一个方法 getArgs
,那么当 test.groovy 引用 args 时,静态编译器会调用对该方法的调用。
groovyc --configscript config.groovy -b StaticBase test.groovy
java -cp .;%GROOVY_HOME%\lib\groovy-2.5.3.jar test 1 2
test.class中的代码有一个运行方法,其代码代表this.println(this.getArgs().length)