升级WebSphere与JDK后Runtime.exec行为变更的具体原因咨询
Great question—this issue ties directly to a specific change in IBM's JDK behavior around command parsing, and that misspelled system property you suspected is indeed at the heart of it. Let's break down exactly what happened:
1. The Misspelled System Property That Masked Your Issue
In older IBM JDK versions (like the one bundled with WebSphere 8.5), there was a typo in a system property: jdk.lang.Process.allowAmbigousCommands (note the missing u in "ambiguous"). This property defaulted to true, enabling a "lenient" command parsing mode in Runtime.exec().
What this meant was: even when you passed a String[] of parameters, the JDK might do extra processing on elements containing special characters (like pipes | or spaces). In your case, this lenient mode happened to make your command work—even though it was relying on non-standard behavior that wasn't guaranteed to work long-term.
2. IBM's JDK Fixes That Broke Your Code
When you upgraded to WebSphere 9.0 (and its bundled JDK), IBM made three critical changes here:
- They corrected the property name to the proper spelling:
jdk.lang.Process.allowAmbiguousCommands - They changed the default value of this corrected property from
truetofalse - They completely removed support for the old misspelled
allowAmbigousCommandsproperty
With allowAmbiguousCommands set to false, Runtime.exec() switched to strict parameter parsing. Instead of treating your shell command string (/opt/mycommand myparam | sed ...) as a single, cohesive argument to sh -c, the strict mode applied unintended escaping or splitting. The end result? The shell received the command string in a way that made it interpret /opt/mycommand myparam as a single executable name (instead of mycommand with myparam as an argument), hence the "missing parameter" error from mycommand.
3. Why ProcessBuilder Works
ProcessBuilder was designed from the start to use strict, straightforward parameter passing. It doesn't rely on the allowAmbiguousCommands property at all—it passes each element of your parameter array directly to the OS's process creation interface without extra processing.
When you use ProcessBuilder("sh", "-c", "/opt/mycommand myparam | sed ..."), the sh process receives your full command string as exactly one argument to the -c flag. The shell can then parse that string normally, correctly identifying myparam as the argument to mycommand.
Quick Recap
- Old IBM JDK's lenient (and misspelled) property let your
Runtime.exec()code work by accident - New JDK fixes removed that leniency, exposing the parsing issue
ProcessBuilderavoids the problem entirely by using consistent, strict parameter handling
内容的提问来源于stack exchange,提问作者Sinc

