Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Gradle:使用项目类路径执行Groovy交互式shell_Java_Shell_Groovy_Gradle - Fatal编程技术网

Java Gradle:使用项目类路径执行Groovy交互式shell

Java Gradle:使用项目类路径执行Groovy交互式shell,java,shell,groovy,gradle,Java,Shell,Groovy,Gradle,我有一个由几个子项目组成的Gradle项目。我刚刚创建了一个新的Groovy shell来添加对交互式Groovy shell的支持,我想使用它来运行: gradle console 或 因此,我的新控制台模块的build.gradle文件如下所示: apply plugin: 'groovy' apply plugin:'application' mainClassName = 'org.codehaus.groovy.tools.shell.Main' dependencies {

我有一个由几个子项目组成的Gradle项目。我刚刚创建了一个新的Groovy shell来添加对交互式Groovy shell的支持,我想使用它来运行:

gradle 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:run
Groovy Shell (2.2.2, JVM: 1.6.0_45)
Type 'help' or '\h' for help.
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
groovy:000> 
BUILD SUCCESSFUL

Total time: 4.529 secs
giovanni@mylaptop:~/Projects/my-project$
因此,交互式shell似乎启动了,但它立即退出

我做错什么了吗

编辑:将以下内容添加到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控制台
立即退出:

$ ./gradlew console
配置项目: Task.leftShift(Closure)方法已被弃用,并计划在Gradle 5.0中删除。请改用Task.doLast(操作)。 运行(/home/jhe052/eclipse workspace/QuinCe/build.gradle:118) (使用--stacktrace运行以获取此弃用警告的完整堆栈跟踪。)

3s建设成功 3项可执行任务:1项已执行,2项最新


替换leftShift(Gradle目前无法很好地处理ncurses风格的控制台应用程序。请在单独的控制台中运行
groovysh
,或者运行
groovyConsole

这适用于JDK 7+(对于JDK 6,请参见下图):

或者,如果你从gradle那里听到很多噪音:

gradle console -q

我创建了一个gradle插件,允许使用这个()。遗憾的是,gradle没有为支持REPL的IO提供有用的API/契约,因此该插件不能与较新版本的gradle一起使用

但是,在github上的文档中,您可以找到一个

该解决方案的概要如下:

package shell;

import org.codehaus.groovy.tools.shell.Main;
import org.fusesource.jansi.AnsiConsole;

class ShellMain {
  public static void main(String[] args) {
    // workaround for jAnsi problems, (backspace and arrow keys not working)
    AnsiConsole.systemUninstall();
    Main.main(args);
  }
}
然后使用JavaExec任务来运行

apply plugin: 'java'

dependencies {
  compile('commons-cli:commons-cli:1.2')
  compile('org.codehaus.groovy:groovy-all:2.4.4') { force = true }
  // when using groovy < 2.2 above: "jline:jline:1.0"
  compile("jline:jline:2.11") {
    exclude(group: 'junit', module: 'junit')
  }
}

task shell(dependsOn: 'testClasses', type: JavaExec) {
  doFirst {
    if (getProperty('org.gradle.daemon') == 'true') {
        throw new IllegalStateException('Do not run shell with gradle daemon, it will eat your arrow keys.')
    }
  }
  standardInput = System.in
  main = 'shell.ShellMain'
  classpath = sourceSets.main.runtimeClasspath
  jvmArgs = []
}
apply插件:“java”
依赖关系{
编译('commons-cli:commons-cli:1.2')
编译('org.codehaus.groovy:groovy-all:2.4.4'){force=true}
//使用上面的groovy<2.2时:“jline:jline:1.0”
编译(“jline:jline:2.11”){
排除(组:“junit”,模块:“junit”)
}
}
任务shell(dependsOn:'testClasses',类型:JavaExec){
首先{
if(getProperty('org.gradle.daemon')=='true'){
抛出新的IllegalStateException('不要用gradle守护进程运行shell,它会吃掉你的箭头键。')
}
}
standardInput=System.in
main='shell.ShellMain'
classpath=sourceset.main.runtimeClasspath
jvmArgs=[]
}

你试过并调试过看会发生什么吗?我怀疑shell看到了EOF,这就是它存在的原因。我如何调试它?我是从命令行运行的。如果你是对的,必须有一个渐变选项不发送到控制台EOF。不过,在此之前,我不知道应用程序插件,但有可能分叉吗?另一个“凭空"假设是,由于您不使用fork,所以使用的JVM就是运行gradle的JVM,gradle关闭了Startupbook上的stdin,这是一个好问题。我相信它确实使用fork。是的,它在a中。是的,我想我最终会使用
groovysh
。我不喜欢
groovyConsole
,因为它不是交互式的。不幸的是,我使用的是JDK 6,所以
ProcessBuilder
类与之大不相同,上面的方法不起作用。最好是升级到JDK 7或8,因为Oracle不再支持JDK 6:同时,您可以尝试使用ProcessBuilder API使其工作,例如设置redirectErrorStream(true)。我将在一段时间内处理它,并尝试为JDK 6想出一个解决方案。向唱诗班宣讲。我正在开发一个遗留应用程序。我在最初的答复中添加了JDK 6的解决方案……几年后:对我来说,这种方法不起作用(使用java 1.8).运行
/gradlew控制台
在成功构建后立即退出。有人知道为什么吗?Gradle 4.4.1、Groovy 2.4.12、Ubuntu16.04上的Java 1.8.0151谢谢!
getProperty('org.Gradle.daemon'))
失败了,但当我删除doFirst块时,这种方式起到了作用。但是,有som Gradle输出干扰了shell输入,因此它不是非常有用。我将尝试进一步修改它……它从来没有完美地工作过,Gradle没有IO API,并且它们在版本之间更改IO行为。Gradle输出看起来非常酷通过这种方式,但它杀死了REPL用例。也许你可以将自定义的“ShellMain”类变成一个实际的应用程序,在没有gradle的情况下启动(也可以从IDE启动)或由gradle构建。使用
/gradlew--console plain-q--no-daemon shell
启动gradle更好,现在对我来说已经足够好了。谢谢你的帮助!
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 console -q
package shell;

import org.codehaus.groovy.tools.shell.Main;
import org.fusesource.jansi.AnsiConsole;

class ShellMain {
  public static void main(String[] args) {
    // workaround for jAnsi problems, (backspace and arrow keys not working)
    AnsiConsole.systemUninstall();
    Main.main(args);
  }
}
apply plugin: 'java'

dependencies {
  compile('commons-cli:commons-cli:1.2')
  compile('org.codehaus.groovy:groovy-all:2.4.4') { force = true }
  // when using groovy < 2.2 above: "jline:jline:1.0"
  compile("jline:jline:2.11") {
    exclude(group: 'junit', module: 'junit')
  }
}

task shell(dependsOn: 'testClasses', type: JavaExec) {
  doFirst {
    if (getProperty('org.gradle.daemon') == 'true') {
        throw new IllegalStateException('Do not run shell with gradle daemon, it will eat your arrow keys.')
    }
  }
  standardInput = System.in
  main = 'shell.ShellMain'
  classpath = sourceSets.main.runtimeClasspath
  jvmArgs = []
}