在Windows中,使用ProcessBuilder执行“java”命令似乎无法正常工作(Kotlin)。

huangapple go评论85阅读模式
英文:

Executing command in ProcessBuilder does not seem to work for "java" commands in Windows (Kotlin)

问题

目前正在尝试以编程方式执行一个 .jar 文件。但为了测试 Java,我尝试运行以下代码:

```java
val p = ProcessBuilder("cmd.exe", "/c", "java", "-version").start()
val results: List<String> = p.inputStream.bufferedReader().readLines()
assertThat("Results should contain java version: ", results, hasItem(containsString("java version")))

然而,似乎没有任何输出。

我成功地运行了以下代码:

val pb = ProcessBuilder("cmd.exe", "/c", "echo", "hello world")

我已经尝试过在 Java 可执行文件所在的工作目录中添加工作目录,但什么都没有发生。
我已经想尽了办法,不知道如何使这个工作。如果我在命令提示符中输入 java -version,我可以得到版本信息。

还可以做些什么来使这个工作起来?


<details>
<summary>英文:</summary>

Currently trying to execute a .jar file programmatically. But to test out java, I tried running the the following:

val p = ProcessBuilder("cmd.exe", "/c", "java", "-version").start()
val results: List<String> = p.inputStream.bufferedReader().readLines()
assertThat("Results should contain java version: ", results, hasItem(containsString("java version")))


However, nothing seems to output.

I am successfully able to run:

val pb = ProcessBuilder("cmd.exe", "/c", "echo", "hello world")


I have tried adding a working directory where the java executable is located, but nothing happens.
I am running out of ideas on how to make this work. If I run cmd and type out `java -version` I get the version information.

What else could I do to get this to work?

</details>


# 答案1
**得分**: 2

`ProcessBuilder`将命令`java -version`的结果写入错误输出`Process.errorStream`,而不是`Process.inputStream`。

尝试以下代码:
```koltin
val results: List<String> = p.errorStream.bufferedReader().readLines()

你也可以尝试使用**Koproc**库。

这是一个基于Java ProcessBuilder的小型Kotlin库,用于运行进程并执行命令。

你可以使用timeout = 120秒来运行java进程:

val koproc = "java -jar some.jar".startProcess { timeoutSec = 120 }

koproc.use {
    println("Out: ${it.readAvailableOut}")
    println("Err: ${it.readAvailableErrOut}")
}

println("Full result after closing: ${koproc.result}")

运行cmd命令:

// 在超时后,'cmd.exe'进程将被关闭
val commandResult = "cmd.exe dirs".startCommand { timeoutSec = 1 }

// 但你将获得输出
println("Out: ${commandResult.out}")

在单元测试中查看示例:https://github.com/kochetkov-ma/koproc/blob/main/src/test/kotlin/ru/iopump/koproc/ExtensionKtIT.kt

英文:

ProcessBuilder writes the result of command java -version to error output Process.errorStream, not Process.inputStream.

Try this code:

val results: List&lt;String&gt; = p.errorStream.bufferedReader().readLines()

Also you may try Koproc lib

It's a small Kotlin lib to run process and execute commands based on Java ProcessBuilder

You may run java process with timeout = 120 sec :

val koproc = &quot;java -jar some.jar&quot;.startProcess { timeoutSec = 120 }

koproc.use {
    println(&quot;Out: ${it.readAvailableOut}&quot;)
    println(&quot;Err: ${it.readAvailableErrOut}&quot;)
}

println(&quot;Full result after closing: ${koproc.result}&quot;)

Run cmd command:

// &#39;cmd.exe&#39; process will be closed after timeout
val commandResult = &quot;cmd.exe dirs&quot;.startCommand { timeoutSec = 1 }

// But you will get the output
println(&quot;Out: ${commandResult.out}&quot;)

See examples in unit tests: https://github.com/kochetkov-ma/koproc/blob/main/src/test/kotlin/ru/iopump/koproc/ExtensionKtIT.kt

huangapple
  • 本文由 发表于 2020年10月7日 03:17:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/64232432.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定