2015-11-25 90 views
1

这里有奇怪的行为。下面的Groovy代码片段(由Java文件从jar文件执行)用于启动一个始终必须运行的控制台程序。它在Java 1.7.0_80和Groovy 2.3.10下运行时完美启动。它使用'envList'的原因是,如果检测到控制台应用程序已经消失,那么它将被其他程序随后调用。第二部分也适用于那些Java和Groovy版本。在Java 8下运行时,此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脚本的输出。由于它在命令行中工作,所以我没有任何错误信息 - 所有各种日志文件都是干净的,没有ERROR或Exceptions。

难住了这个问题,尽管我不希望明确的答案,任何建议什么尝试或如何进行会帮助我极大。

+0

它说什么,如果你加上'console.consumeProcessOutput(的System.out,System.err的)'前'waitForOrKill'​​? –

+0

奇怪的是,它为Java 1.7和1.8提供了相同的输出(来自shell脚本)。我正在尝试捕获现在两种用法的所有环境变量。 – JoeG

+0

Java 8没有PermGen。 (不清楚JVM_SIZE_PERM的用途) – Jayan

回答

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 
} 

什么在这个解决方案是脆?

  • 如果我调用第二个executeOnShell方法的工作目录,而不是默认的,它会失败。这两种方法的Java 7
  • 我永远无法在原来的问题的工作概括的“更时髦”的做法下,做工精细。仍然想知道这一点。
  • 如果“consumeProcessOutput”不会被调用(和使用任何替代机制),它也不起作用。

如果有人在意解释这一切,我想很多人会感兴趣。无论如何,这里至少有一个解决方法。