英文:
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<String> = 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 = "java -jar some.jar".startProcess { timeoutSec = 120 }
koproc.use {
println("Out: ${it.readAvailableOut}")
println("Err: ${it.readAvailableErrOut}")
}
println("Full result after closing: ${koproc.result}")
Run cmd
command:
// 'cmd.exe' process will be closed after timeout
val commandResult = "cmd.exe dirs".startCommand { timeoutSec = 1 }
// But you will get the output
println("Out: ${commandResult.out}")
See examples in unit tests: https://github.com/kochetkov-ma/koproc/blob/main/src/test/kotlin/ru/iopump/koproc/ExtensionKtIT.kt
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论