如果您对java–GroovyShell:嵌入式执行感兴趣,那么本文将是一篇不错的选择,我们将为您详在本文中,您将会了解到关于java–GroovyShell:嵌入式执行的详细内容,我们还将为您解答j
如果您对java – GroovyShell:嵌入式执行感兴趣,那么本文将是一篇不错的选择,我们将为您详在本文中,您将会了解到关于java – GroovyShell:嵌入式执行的详细内容,我们还将为您解答java做嵌入式的相关问题,并且为您提供关于Gradle:使用项目类路径执行Groovy交互式Shell、Groovy - GroovyShell、groovy hello world 第一个groovy程序、groovy – 使用选项和参数执行shell脚本的有价值信息。
本文目录一览:- java – GroovyShell:嵌入式执行(java做嵌入式)
- Gradle:使用项目类路径执行Groovy交互式Shell
- Groovy - GroovyShell
- groovy hello world 第一个groovy程序
- groovy – 使用选项和参数执行shell脚本
java – GroovyShell:嵌入式执行(java做嵌入式)
我正在尝试将groovy嵌入到大型Java应用程序中.
Java应用程序应该在启动时加载一些实用程序Groovy脚本.
然后应用程序应该多次运行其他脚本.还需要在GUI处输入一些代码并在用户请求时执行它.
我面临的问题是:
我正在加载启动脚本,如下所示:
groovyshell gShell = new groovyshell();
gShell.evaluate(new FileReader("scripts/autoload.groovy"));
假设我的autoload.groovy包含:
def prnt(m) {
println("From Groovy: " + m);
}
这很好用.但是,当我想使用以下命令运行用户命令时:
gShell.evaluate("prnt 66");
我收到错误:
groovy.lang.MissingMethodException:没有方法签名:Script2.prnt()适用于参数类型:(java.lang.Integer)值:[66]
我的用户脚本如何访问已加载的方法?
注意:我也试过“autoload.prnt 88”,仍然得到错误.
def prnt(m) {
println("From Groovy: " + m);
}
定义从autoload.groovy生成的Script类中的方法,该方法无法从后续的“调用”脚本访问.但是,由同一groovyshell运行的脚本共享相同的绑定,因此您可以在一个脚本的绑定中存储值,并在另一个脚本中访问它们.在绑定中存储值只是将值分配给另外未声明的变量:
prnt = { m ->
println("From Groovy: " + m);
}
这将在绑定变量prnt中存储闭包,您可以从同一shell中的其他脚本调用闭包.注意
def prnt = { m ->
要么
Closure prnt = { m ->
不起作用,因为def或类型使它成为局部变量声明(对这个特定脚本是私有的),而不是对绑定的赋值.
Gradle:使用项目类路径执行Groovy交互式Shell
我有一个由几个子项目组成的Gradle项目。我刚刚创建了一个新的应用程序,以添加对我想运行的交互式Groovy Shell的支持:
gradle console
要么
gradle console:run
因此,我新console
模块的build.gradle文件如下:
apply plugin: ''groovy''apply plugin:''application''mainClassName = ''org.codehaus.groovy.tools.shell.Main''dependencies { compile ''org.codehaus.groovy:groovy-all:2.2.2'' compile ''org.fusesource.jansi:jansi:1.11'' compile ''commons-cli:commons-cli:1.2'' compile ''jline:jline:2.11'' compile project('':my-module'')}task(console, dependsOn: ''classes'', type: JavaExec) { main = ''org.codehaus.groovy.tools.shell.Main'' classpath = sourceSets.main.runtimeClasspath}
但是,当我跑步gradle :console:run
或gradle console
得到类似以下信息时:
:console:runGroovy Shell (2.2.2, JVM: 1.6.0_45)Type ''help'' or ''\h'' for help.--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------groovy:000> BUILD SUCCESSFULTotal time: 4.529 secsgiovanni@mylaptop:~/Projects/my-project$
因此,交互式外壳似乎开始了,但立即退出了。
难道我做错了什么?
编辑 :将以下内容添加到build.gradle文件:
run.standardInput = System.in
现在,从输入流中读取标准输入(由于注释)。
但是,Gradle似乎对此卡住了:
Groovy Shell (2.2.2, JVM: 1.6.0_45)Type ''help'' or ''\h'' for help.--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------groovy:000> > Building 88% > :console:run
并且没有输入被接受。即使这样也会导致相同的结果:
gradle --no-daemon console:run
更新2018:
Dylons接受的答案似乎不再起作用,./gradlew console
立即退出:
$ ./gradlew console
配置项目:Task.leftShift(Closure)方法已被弃用,并计划在Gradle
5.0中删除。请改用Task.doLast(Action)。在build_8qb2gvs00xed46ejq1p63fo92.run(/home/jhe052/eclipse-
workspace/QuinCe/build.gradle:118)(使用–stacktrace运行以获取此弃用警告的完整堆栈跟踪。)在3秒钟内成功建立3项可执行的任务:1项已执行,2项最新
用doLast替换leftShift(<<)会删除不赞成使用的消息,但结果相同。版本信息:
$ ./gradlew --version
摇篮4.4.1
建立时间:2017年12月20日15:45:23 UTC修订版:10ed9dc355dc39f6307cc98fbd8cea314bdd381c
Groovy:2.4.12 Ant:2017年2月2日编译的Apache Ant(TM)版本1.9.9 JVM:1.8.0_151(Oracle
Corporation 25.151-b12)OS:Linux 4.13.0-32-通用amd64
答案1
小编典典这适用于JDK 7+(对于JDK 6,请参见下图):
configurations { console}dependencies { // ... compile dependencies, runtime dependencies, etc. console ''commons-cli:commons-cli:1.2'' console(''jline:jline:2.11'') { exclude(group: ''junit'', module: ''junit'') } console ''org.codehaus.groovy:groovy-groovysh:2.2.+''}task(console, dependsOn: ''classes'') << { def classpath = sourceSets.main.runtimeClasspath + configurations.console def command = [ ''java'', ''-cp'', classpath.collect().join(System.getProperty(''path.separator'')), ''org.codehaus.groovy.tools.shell.Main'', ''--color'' ] def proc = new ProcessBuilder(command) .redirectOutput(ProcessBuilder.Redirect.INHERIT) .redirectInput(ProcessBuilder.Redirect.INHERIT) .redirectError(ProcessBuilder.Redirect.INHERIT) .start() proc.waitFor() if (0 != proc.exitValue()) { throw new RuntimeException("console exited with status: ${proc.exitValue()}") }}
为了使此功能适用于JDK
6,我从http://codingdict.com/questions/113978修改了解决方案。我的解决方案是针对标准Linux终端量身定制的,因此,如果您运行的外壳使用换行符使用’\
n’以外的char序列或将退格编码为其他127以外的值,则可能需要对其进行一些修改。我不确定如何正确打印颜色,因此它的输出相当单调,但是可以完成工作:
configurations { console}dependencies { // ... compile dependencies, runtime dependencies, etc. console ''commons-cli:commons-cli:1.2'' console(''jline:jline:2.11'') { exclude(group: ''junit'', module: ''junit'') } console ''org.codehaus.groovy:groovy-groovysh:2.2.+''}class StreamCopier implements Runnable { def istream def ostream StreamCopier(istream, ostream) { this.istream = istream this.ostream = ostream } void run() { int n def buffer = new byte[4096] while ((n = istream.read(buffer)) != -1) { ostream.write(buffer, 0, n) ostream.flush() } }}class InputCopier implements Runnable { def istream def ostream def stdout InputCopier(istream, ostream, stdout) { this.istream = istream this.ostream = ostream this.stdout = stdout } void run() { try { int n def buffer = java.nio.ByteBuffer.allocate(4096) while ((n = istream.read(buffer)) != -1) { ostream.write(buffer.array(), 0, n) ostream.flush() buffer.clear() if (127 == buffer.get(0)) { stdout.print("\b \b") stdout.flush() } } } catch (final java.nio.channels.AsynchronousCloseException exception) { // Ctrl+D pressed } finally { ostream.close() } }}def getChannel(istream) { def f = java.io.FilterInputStream.class.getDeclaredField("in") f.setAccessible(true) while (istream instanceof java.io.FilterInputStream) { istream = f.get(istream) } istream.getChannel()}task(console, dependsOn: ''classes'') << { def classpath = sourceSets.main.runtimeClasspath + configurations.console def command = [ ''java'', ''-cp'', classpath.collect().join(System.getProperty(''path.separator'')), ''org.codehaus.groovy.tools.shell.Main'' ] def proc = new ProcessBuilder(command).start() def stdout = new Thread(new StreamCopier(proc.getInputStream(), System.out)) stdout.start() def stderr = new Thread(new StreamCopier(proc.getErrorStream(), System.err)) stderr.start() def stdin = new Thread(new InputCopier( getChannel(System.in), proc.getOutputStream(), System.out)) stdin.start() proc.waitFor() System.in.close() stdout.join() stderr.join() stdin.join() if (0 != proc.exitValue()) { throw new RuntimeException("console exited with status: ${proc.exitValue()}") }}
然后,通过以下方式执行:
gradle console
或者,如果您从gradle中听到很多噪音:
gradle console -q
Groovy - GroovyShell
Summary
- 执行一个外部的脚本。
- 如果单独执行一个脚本我们一行一行写就行,如果需要传入参数,返回参数,我们就定义一个 Closure
Demo
import groovy.json.JsonSlurper
class Main {
static void main(args) {
def shell = new groovyshell()
// 要执行的脚本内容,是一行一行的代码,在 shell.evaluate(script) 的时候,就是逐行执行。
// 如果最后有 return 语句,就可以接收返回结果。
String script =
"""
println 'Script!'
return "222"
"""
def scriptResult = shell.evaluate(script)
// 要执行的脚本内容是一个 Closure 对象,在执行的时候就返回一个 Closure 对象,
// 调用该 Closure 对象的 call() 方法,获取对应的值。
String closure =
"""
{ dataMap -> println "Groovy!"; return "返回值"}
"""
// 返回的是 Script 对象,对象里面是一个 Closure 对象,需要执行才能返回结果。
def closureResult = shell.evaluate(closure)
println(closureResult())
}
}
Demo
package info.aoye
import grails.gorm.transactions.Transactional
@Transactional
class ComponentDemoService {
static scope = "singleton"
// 传递过来一个组件对象脚本对象,一个 Object 类型 param
def evaluate(Component component, Object object) {
def shell = new groovyshell()
def closure
def result
try
{
closure = shell.evaluate(component?.script)
// 如果不需要参数,就直接执行脚本
if (!object)
{
println("111")
result = closure
}
else
{
// 如果是有参数,返回 Closure 对象,这里需要执行一下这个 Closure。
result = closure(object)
}
}
catch (Exception e)
{
println e
result = e
}
return result
}
}
groovy hello world 第一个groovy程序
vi hello.groovy
输入:
def hello = { who -> println "hello ${who}" } hello("groovy")
运行:
$ groovy hello.groovy
返回结果:hello groovy
groovy – 使用选项和参数执行shell脚本
当我在服务器上手动运行它时,它可以工作:
/ bin / bash -c’/ some / script MyProduct SomeBranch’
当我用groovy运行它时,它不起作用.
我得到了同样的错误,好像我没有传递“-c”选项,所以不知何故“-c”不起作用.
这是我的代码:
branchName = "SomeBranch" configName = "release" println "Building for branch "+branchName+" and configuration "+configName def chkbranch = { String product,String branch -> mkcmd( product,branch ) } private def mkcmd ( String product,String branch ) { // Build the command string to run def cmd = "/bin/bash -c ''/some/script "+product+" "+branch+"''" def sout = new StringBuffer() def serr = new StringBuffer() // Run the command println "running "+cmd def proc = cmd.execute() proc.consumeProcessOutput ( sout,serr ) proc.waitForProcessOutput () println "out> $sout" println "err> $serr" return sout } chkbranch ( "MyProduct",branchName )
这是在Groovy中构建命令的正确方法吗?:
def cmd = "/bin/bash -c ''/some/script "+product+" "+branch+"''" cmd.execute()
谢谢!
我试过类似/有用资源的问题:
> groovy execute with parameters containing spaces
> Groovy executing shell commands
> http://www.joergm.com/2010/09/executing-shell-commands-in-groovy/
> https://fbflex.wordpress.com/2011/11/30/replacing-the-groovy-execute-method-with-one-that-prints-output-while-the-process-is-running/
解决方法
def cmd = ["/bin/bash","-c","/some/script",product,branch]
您也可以尝试:
def cmd = ["/some/script",branch]
if / some / script是可执行的 – BTW是否置于root(/)下?
关于java – GroovyShell:嵌入式执行和java做嵌入式的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于Gradle:使用项目类路径执行Groovy交互式Shell、Groovy - GroovyShell、groovy hello world 第一个groovy程序、groovy – 使用选项和参数执行shell脚本的相关知识,请在本站寻找。
本文标签: