|
| 1 | +--- |
| 2 | +id: e27cf2f6-ae52-4d75-a481-0fd04dbf2999 |
| 3 | +slug: "runtime-exec-to-process-builder" |
| 4 | +title: "Runtime.exec(String) to ProcessBuilder arguments" |
| 5 | +category: "tooling" |
| 6 | +difficulty: "intermediate" |
| 7 | +jdkVersion: "5" |
| 8 | +oldLabel: "Command string" |
| 9 | +modernLabel: "ProcessBuilder" |
| 10 | +oldApproach: "Runtime.exec(String)" |
| 11 | +modernApproach: "ProcessBuilder" |
| 12 | +oldCode: |- |
| 13 | + Process process = Runtime.getRuntime() |
| 14 | + .exec("git show " + revision); |
| 15 | +modernCode: |- |
| 16 | + Process process = new ProcessBuilder( |
| 17 | + "git", "show", revision) |
| 18 | + .redirectErrorStream(true) |
| 19 | + .start(); |
| 20 | +summary: "Launch processes with an explicit argument list and ProcessBuilder configuration." |
| 21 | +explanation: "Runtime.exec(String) applies Java's command-string tokenization, which\ |
| 22 | + \ is easy to misunderstand when arguments contain spaces or quoting. ProcessBuilder\ |
| 23 | + \ accepts program arguments as distinct values and exposes the working directory,\ |
| 24 | + \ environment, input/output redirects, and error-stream policy explicitly. It does\ |
| 25 | + \ not invoke a shell unless the application deliberately launches one." |
| 26 | +whyModernWins: |
| 27 | +- icon: "🎯" |
| 28 | + title: "Exact arguments" |
| 29 | + desc: "Each process argument remains a distinct value without command-string tokenization." |
| 30 | +- icon: "🎛" |
| 31 | + title: "Explicit configuration" |
| 32 | + desc: "Environment, directory, redirects, and error handling are configured together." |
| 33 | +- icon: "🛡" |
| 34 | + title: "Safer boundaries" |
| 35 | + desc: "Avoids constructing a shell-like command string from dynamic values." |
| 36 | +support: |
| 37 | + state: "available" |
| 38 | + description: "Widely available since JDK 5 (September 2004)" |
| 39 | +prev: "tooling/junit6-with-jspecify" |
| 40 | +next: "language/anonymous-classes-to-lambdas" |
| 41 | +related: |
| 42 | +- "concurrency/process-api" |
| 43 | +- "io/inputstream-transferto" |
| 44 | +- "security/security-manager-migration" |
| 45 | +tags: |
| 46 | +- tooling |
| 47 | +- security |
| 48 | +docs: |
| 49 | +- title: "ProcessBuilder" |
| 50 | + href: "https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/lang/ProcessBuilder.html" |
| 51 | +- title: "Runtime.exec(String)" |
| 52 | + href: "https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/lang/Runtime.html#exec(java.lang.String)" |
0 commit comments