学习 JDK Process操作子进程的API;包含ProcessBuilder、Process、ProcessHandler核心类API的使用演示以及在不同场景下的案例;
|
|
1 hafta önce | |
|---|---|---|
| src | 1 hafta önce | |
| .gitignore | 1 hafta önce | |
| AGENTS.md | 1 hafta önce | |
| README.md | 1 hafta önce | |
| blog.md | 1 hafta önce | |
| blog2.md | 1 hafta önce | |
| doc.md | 1 hafta önce | |
| pom.xml | 1 hafta önce | |
| process.md | 1 hafta önce | |
| template.md | 1 hafta önce |
Maven 单模块示例工程(目标 Java 17),用于学习 ProcessBuilder / Process / ProcessHandle:如何构建一个子进程、读写它的标准输入输出、重定向流、异步处理 I/O、获取执行状态码,以及组合成管道式调用和进程树管理。
所有说明文档与代码注释均为中文,配套教程见 process.md(大纲)、doc.md(完整教程)与 blog.md / blog2.md(博客文章)。
maven.compiler.source/target = 17,UTF-8 编码)logback-classic(提供 SLF4J 日志)junit-jupiter(JUnit 5,由 maven-surefire-plugin 驱动)exec-maven-pluginsrc/main/java/space/anyi/process/ 示例代码(public static void main 入口)
Jdk.java 共享工具:javac/java 绝对路径、编译 fixture
QuickStart.java 示例一:构建并运行子进程
ProcessIOExample.java 示例二:标准输入/输出/错误流
ProcessRedirectExample.java 重定向:合并流、文件重定向、Redirect 枚举
ProcessAsyncExample.java 异步:线程 / CompletableFuture / onExit
ExecuteStatusExample.java 示例三:waitFor 阻塞与超时销毁
ProcessBuilderExample.java 环境变量(environment())
ProcessPipelineExample.java 示例五:管道式组合调用
ProcessHandleExample.java 示例六:ProcessHandle 进程管理
src/main/resources/code/ 子进程程序(fixtures),各目录含 Main.java
hello/ 打印问候语与 PID
io/ 回显 stdin、统计并写入 stderr
executeStatus/ 睡眠 10 秒后退出
processHandle/ 打印 PID/参数,睡眠 30 秒等待父进程观察
src/test/java/space/anyi/process/ ProcessMechanicsTest(端到端测试)
doc.md / process.md / blog.md / blog2.md 教程与博客文档
工程没有运行目标,编译后手动运行。需要把依赖 jar 一起放到 classpath(示例使用 slf4j 日志),否则出现 NoClassDefFoundError: org/slf4j/LoggerFactory。
mvn -q compile
java -cp "target/classes:$(mvn -q dependency:build-classpath -Dmdep.outputFile=/dev/stdout | tail -1)" space.anyi.process.<ClassName>
例如:
java -cp "target/classes:$(mvn -q dependency:build-classpath -Dmdep.outputFile=/dev/stdout | tail -1)" space.anyi.process.QuickStart
注意:示例的
workDir相对于user.dir,必须从仓库根目录运行,否则ProcessBuilder.start()抛IOException: error=2。
mvn test
ProcessMechanicsTest 端到端驱动同一批 child fixtures(会先重新编译 io/ 与 executeStatus/),并刻意覆盖「流排水 + 超时/destroy」的常见陷阱。同样要求从仓库根目录运行。
new BufferedReader(...).lines().forEach(...) 会阻塞当前线程直到子进程退出;做限时 waitFor(timeout) 时必须在后台线程排水。Process.waitFor(timeout, unit) 返回的是 boolean 而非退出码;超时返回 false 时子进程仍存活,此时调用 exitValue() 会抛 IllegalThreadStateException,须先 destroy() 再阻塞 waitFor()。error=2),请统一走 Jdk.javac() / Jdk.java() 的绝对路径,不要裸用 javac / java。static 方法演示,统一由 main() 调用。src/main/resources/code/,不使用临时脚本或系统命令。