The Go rewrite of the Java buildpack changed how JAVA_OPTS is assembled and
passed to the JVM. If you are migrating configs written for the Ruby buildpack,
the escaping rules are different.
| Mechanism | Ruby buildpack | Go buildpack |
|---|---|---|
| Launch | eval exec java $JAVA_OPTS ... |
javaexec (shell-free tokenizer) |
$VAR in opts |
expanded by shell at eval | expanded by profile.d at container start |
$(cmd) in opts |
executed by shell | never executed (security fix, #1301) |
\ handling |
eval consumed one level of backslashes | javaexec POSIX: \\→\, \" → " |
* glob |
expanded against filesystem | literal |
Both buildpacks expand $VAR references at runtime. No escaping needed or supported.
# Works the same in both buildpacks
cf set-env my-app JAVA_OPTS '-Dserver.port=$PORT'To prevent expansion, \$ works in both buildpacks: \$VAR delivers the
literal text $VAR to the JVM without expanding it.
# Ruby buildpack: \\\\ in the manifest/env → \\ after eval → \ to JVM
# Go buildpack: \\ in the manifest/env → \ to JVM (POSIX tokenizer, one level)| Want to deliver to JVM | Ruby buildpack (env) | Go buildpack (env) |
|---|---|---|
one \ |
\\\\ |
\\ |
two \\ |
\\\\\\\\ |
\\\\ |
literal \$PORT |
\\\\\$PORT |
not supported — $PORT expands |
# Ruby buildpack: must be quoted carefully to survive eval and glob expansion
# Go buildpack: write literally — * never globs, no eval
cf set-env my-app JAVA_OPTS '-DcronExpr=0 */7 * * *'# Ruby buildpack: $(hostname) in JAVA_OPTS was EXECUTED and replaced with output
# Go buildpack: $(hostname) reaches the JVM as the literal string $(hostname)
# This is intentional — executing user-supplied commands is unsafe-
Remove extra backslashes. Replace
\\\\with\\— the old pattern survived two shell parse layers (eval) which no longer exist. -
\$VARstill works. Keep any\$VARescapes you have — they are honoured and pass the literal$VARtext to the JVM in both buildpacks. -
Cron / glob expressions. Remove any protective quoting that was needed to survive
eval— write the expression directly. -
Command substitutions. If you relied on
$(cmd)being executed inJAVA_OPTS(e.g.$(hostname),$(cat /etc/myconfig)), that no longer works. Compute the value before the app starts and set it as a separate environment variable, then reference it via$MYVARinJAVA_OPTS.
- Java Options Framework
- Issue #1301 — remove
evalfrom start command