0

OS: Windows 10, mainly using Cygwin.

I put together a DummyMain.groovy file like so:

@Grab(group='org.jline', module='jline', version='3.7.0')
class DummyMain {

static void main( args ) {
    new DummyMain().go()
}

def go() {
    def terminal = org.jline.terminal.TerminalBuilder.builder().jna( true ).system( true ).build()
    terminal.enterRawMode()
    def reader = terminal.reader()
    int readInt = -1
    while( readInt != 13 ) {
        readInt = reader.read()
        println "read |$readInt| class ${readInt.class.simpleName}"
        println "reader class ${reader.class.simpleName}"
    }
    reader.close()
    terminal.close()
}

}

When I run this by going groovy DummyMain in its own directory this works as expected and fills me with joy: the reader.read() line pauses for the next character, and then processes it (i.e. before the user presses Enter to end the line).

But when I comment out the @Grab and put this line in build.gradle:

compile 'org.jline:jline:3.7.0'

and try to run this file using the simplest possible build.gradle it fails: the while loops spins on endlessly without waiting for user input, i.e. endlessly printing "read |-1|...".

This failure to wait happens if I use a Cygwin console or a Windows CMD console to go gradle run.

From the other print line I can tell that the reader here is class NonBlockingInputStreamReader in all 3 cases (i.e. Gradle via Cygwin, Gradle via Windoze CMD or groovy command line command).

However, I find that if I do a gradle installDist, the resulting "distributed" version of the app works OK: responds to each character entered and waits for the next. Thank God for that! But for testing and development purposes it'd be nice if a solution could be found to the problem of trying to run with Gradle. It seems likely that some tests will fail when they shouldn't as a result of this.

reply to tkruse

here's the build.gradle. DummyMain.groovy is under src\main\groovy\core.

apply plugin: 'java-library'
apply plugin: 'groovy'
apply plugin: 'application'

mainClassName = "core.DummyMain"

repositories {
    jcenter()
    mavenCentral()
}

dependencies {
    api 'org.apache.commons:commons-math3:3.6.1'
    implementation 'com.google.guava:guava:21.0'
    compile 'org.codehaus.groovy:groovy-all:2.6.0-alpha-2'
    compile 'net.bytebuddy:byte-buddy:1.6.11'
    compile 'org.jline:jline:3.7.0'
}

The answerer to the only answer (so far) is the author of JLine. I think it's very unlikely that Gradle uses JLine, and that if that were the case Guillaume Nodet would have mentioned that...

4

1 回答 1

0

I suppose you noticed that in one case, you're referring to jline-terminal-jna while in the other case you're referring to jline. While the jline jar contains the jline-terminal-jna jar content, the dependencies are slightly different, because the JNA library is a mandatory dependency of jline-terminal-jna, but an optional dependency of jline.

You should check the class of the Terminal instance created by JLine and verify that this is the expected JnaWinSysTerminal class.

It could also be related to a JLine issue raised a while ago, https://github.com/jline/jline3/issues/77. However, there's nothing to fix in JLine, and the related gradle issue was rejected and closed (see https://github.com/gradle/gradle/issues/1099).

于 2018-04-16T20:50:50.360 回答