在Java 8下运行时,此Groovy代码无法正常工作

时间:2015-11-25 15:29:48

标签: java groovy

这里有奇怪的行为。下面的Groovy片段(由jar文件中的Java执行)用于启动始终必须运行的控制台程序。它在Java 1.7.0_80和Groovy 2.3.10下运行时完美启动。它使用' envList'的原因如果检测到控制台应用程序已经消失,则随后由另一个程序调用。第二部分也适用于Java和Groovy的那些版本。

List envList = ['JVM_GC_OPTS=', 'JVM_SIZE_PERM=', 'JVM_SIZE=']
String workingDir = "${someDir}/console/bin"
def console = ['/bin/bash', '-c', 
    "${someDir}/console/bin/console.sh start"].execute(envList, new File(workingDir))
console.waitForOrKill(30000)

当Java升级到1.8.0_65时,第一次使用不再有效。但是,如果手动启动(即手动运行shell脚本),则可以测试第二次使用 - 这样可以正常工作。我无法弄清楚如何从程序用法中查看shell脚本的输出。由于它在命令行中运行,因此我没有任何错误信息 - 所有各种日志文件都是干净的,没有错误或异常。

真的坚持这个问题,虽然我没有期待明确的答案,但是对于尝试什么或如何进行的任何建议都会对我有所帮助。

1 个答案:

答案 0 :(得分:0)

我现在有点工作了。在原始问题中我没有提到的一个可能重要的因素是,当我尝试使用Java 8运行时,代码在Java 7的其他地方编译。

解决方案似乎非常脆弱,我不明白它为什么会起作用,而其他变种却不能......

首先,这个(删除了错误处理代码)有效:

def executeOnShell(String command) {
    return executeOnShell(command, new File(System.properties.'user.dir'))
}

def executeOnShell(String command, File workingDir) {
    def process = new ProcessBuilder(addShellPrefix(command))
                                      .directory(workingDir)
                                      .redirectErrorStream(true)
                                      .start()
    StringBuilder sout = new StringBuilder()
    StringBuilder serr = new StringBuilder()
    process.consumeProcessOutput(sout, serr)
    process.waitForOrKill(30000)
    sout.toString()
  }

def addShellPrefix(String command) {
    def commandArray = new String[3]
    commandArray[0] = "sh"
    commandArray[1] = "-c"
    commandArray[2] = command
    return commandArray
}

这个解决方案有什么脆弱?

  • 如果我使用除默认值之外的workingDir调用第二个executeOnShell方法,则会失败。在Java 7下,这两种方式都可以正常工作。
  • 我永远无法获得更加时髦的'原始问题中概述的方法可行。还在想这个。
  • 如果' consumeProcessOutput'没有被调用(并使用任何替代机制)它也不起作用。

如果有人愿意解释这些,我想很多人会感兴趣。无论如何,这里至少记录了一种解决方法。