当前位置: 首页 > 面试题库 >

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

戚锦
2023-03-14
问题内容

我有一个由几个子项目组成的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:rungradle 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$

因此,交互式外壳似乎开始了,但立即退出了。

难道我做错了什么?

编辑 :将以下内容添加到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


问题答案:

这适用于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源文件: 如何为Gradle配置Groovy类路径? Groovy位于

  • 主要内容:Groovy插件,Groovy项目的默认项目布局本章介绍如何使用文件编译和执行Groovy项目。 Groovy插件 Gradle的Groovy插件扩展了Java插件,并为Groovy程序提供了任务。可以使用以下行来应用groovy插件。 完整的构建脚本文件如下。将以下代码复制到文件中。 可以使用以下命令来执行构建脚本。 Groovy项目的默认项目布局 Groovy插件假定Groovy项目有手动做过一定的设置。 包含Groovy源代码; 包含Gr

  • 有没有办法从我的Gradle构建的groovy项目中访问Gradle groovy插件源集目录?我正在寻找默认的gradle src和resources目录。 我需要它来避免在项目中硬编码资源目录,但使用默认的Groovy插件资源目录(resources/main)。

  • 我有一个多项目的构建设置与gradle将包含多个android应用程序和库。 我想应用某些分级插件只对一些子项目。(比如android gradle插件只到android子项目)因此我在和插件声明中添加了类路径依赖项到两个android子项目: 和 。问题是gradle找不到android gradle插件: 错误:(%1,%1)评估项目“:ShopPr:Presentation”时出现问题。找不

  • 问题内容: 我正在使用Gradle的Application插件为独立的Java应用程序生成安装。我有一个配置文件,需要放在类路径中,但似乎无法在sh / bat文件中正确生成它。该配置文件需要位于jar的外部。 conf文件位于目录中,因此当我运行它时,会将其安装在conf目录下,如下所示。 我尝试将这个目录添加到claspath中,如下所示: 但是当我查看sh / bat文件中的类路径时,它会添

  • 本文向大家介绍groovy 在Java项目上使用Groovy,包括了groovy 在Java项目上使用Groovy的使用技巧和注意事项,需要的朋友参考一下 示例 Groovy可以访问所有Java类,实际上Groovy类是Java类,可以直接由JVM运行。如果您正在从事Java项目,那么使用Groovy作为一种简单的脚本语言来与Java代码进行交互就变得很容易了。 为了使事情变得更好,几乎所有Jav