Skip to content

Issue 1259 java opts breaks pre start script#1260

Open
stokpop wants to merge 3 commits intocloudfoundry:mainfrom
stokpop:issue-1259-java-opts-breaks-pre-start-script
Open

Issue 1259 java opts breaks pre start script#1260
stokpop wants to merge 3 commits intocloudfoundry:mainfrom
stokpop:issue-1259-java-opts-breaks-pre-start-script

Conversation

@stokpop
Copy link
Copy Markdown
Contributor

@stokpop stokpop commented Apr 29, 2026

Fixes #1259

The profile.d/00_java_opts.sh script used sed to substitute $JAVA_OPTS, $HOME and $DEPS_DIR into .opts file content. This breaks at runtime when JAVA_OPTS contains:

  • newlines — from YAML block scalar (>) in CF manifest
  • pipe characters (|) — e.g. javaagent options like agent.jar=featureA|featureB
  • & or \ — interpreted as sed replacement metacharacters, causing silent corruption

When sed fails, the script continues without set -e, silently dropping all opts file content. The JVM starts with an empty JAVA_OPTS: no memory limits, no agents.

Changes

  • Normalize JAVA_OPTS to single line at capture time (tr newlines to spaces) before any substitution
  • Replace sed with bash parameter expansion (${var//find/replace}) for $JAVA_OPTS, $HOME and $DEPS_DIR substitutions — no special-character restrictions
  • Add regression tests covering multiline JAVA_OPTS, pipe characters, and $HOME/$DEPS_DIR expansion

Why set -e was not added

profile.d scripts are sourced by the CF launcher, not run in a subshell — set -e would leak to the parent shell. A kill -TERM $$ guard was also considered, but after analysis it provides little value: with sed replaced by bash parameter expansion, there are no remaining commands in the assembly loop that can fail (the substitutions are pure bash builtins). A guard checking for empty JAVA_OPTS would also be imprecise, since the memory calculator appends to JAVA_OPTS via its own separate java.sh script after 00_java_opts.sh runs.

stokpop added 3 commits April 29, 2026 12:33
JAVA_OPTS set via YAML block scalar (>) in manifest.yml may contain
literal newlines when delivered to the shell. The profile.d script
used sed to substitute $JAVA_OPTS into .opts file content, which
fails with "unterminated 's' command" when the value spans multiple
lines.

Fix: normalize USER_JAVA_OPTS to a single line at capture time using
tr to convert newlines to spaces and collapse multiple spaces.

Added test reproducing the exact failure with multiline JAVA_OPTS
containing -javaagent and -Xms/-Xmx/-XX flags.
…script

Using sed to substitute $DEPS_DIR, $HOME and $JAVA_OPTS in opts file
content breaks when those values contain the sed delimiter (|),
backslashes, ampersands, or newlines. All are valid in JAVA_OPTS,
e.g. javaagent options using pipe syntax:

  -javaagent:agent.jar=enableExecutorMBeans|disableMyFeature

Bash parameter expansion (${var//find/replace}) has no special-character
restrictions and replaces sed for these three substitutions.

Adds regression test covering pipe character in JAVA_OPTS.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

pre-start scripts fails when JAVA_OPTS contains special characters

1 participant