Skip to content

refactor: extract BaseJRE to eliminate duplication across standard JRE providers#1288

Open
stokpop wants to merge 2 commits into
cloudfoundry:mainfrom
stokpop:issue-1264-base-jre-refactor
Open

refactor: extract BaseJRE to eliminate duplication across standard JRE providers#1288
stokpop wants to merge 2 commits into
cloudfoundry:mainfrom
stokpop:issue-1264-base-jre-refactor

Conversation

@stokpop
Copy link
Copy Markdown
Contributor

@stokpop stokpop commented May 20, 2026

Closes #1264

Summary

Reduces ~1300 lines of near-identical code in 6 JRE files to a single BaseJRE struct (243 lines) plus thin per-JRE wrappers (~11 lines each).

Design

BaseJRE uses a template method pattern with injected config/function fields so implementers never need to override Supply/Finalize, eliminating the 'forgot to call base' risk from method-override approaches.

Variation points:

  • dirPrefixes/dirExacts: drive findJavaHome directory matching per JRE
  • extraFinalizeOpts: hook for JRE-specific JAVA_OPTS (used by IBM JRE: -Xtune:virtualized -Xshareclasses:none)
  • installErrNote: extra context in install error messages (GraalVM: ensure repository_root is configured)

ZingJRE is intentionally excluded — it has no memory calculator or jvmkill and has genuinely different Finalize behaviour.

Before / After

Before After
openjdk.go 254 lines 11 lines
zulu.go 219 lines 11 lines
sapmachine.go 219 lines 11 lines
ibm.go 223 lines 13 lines
oracle.go 212 lines 11 lines
graalvm.go 219 lines 11 lines
base_jre.go 243 lines
Total 1346 lines 311 lines

Tests

Added standard_jres_test.go covering all 5 non-OpenJDK standard JREs (OpenJDK already had openjdk_test.go). For each JRE:

  • Name() returns the correct display string
  • Detect() triggers on the correct env var and not on others
  • Version() / JavaHome() are empty before installation
  • findJavaHome (via Finalize()) locates the JRE-specific subdirectory prefix correctly

All existing and new tests pass.

stokpop added 2 commits May 20, 2026 12:21
…E providers

Reduces ~1300 lines of near-identical code in 6 JRE files to a single
BaseJRE struct (243 lines) plus thin per-JRE wrappers (~11 lines each).

BaseJRE uses a template method pattern with injected config/function fields
so implementers never need to override Supply/Finalize, eliminating the
'forgot to call base' risk from method-override approaches.

Variation points:
- dirPrefixes/dirExacts: drive findJavaHome directory matching per JRE
- extraFinalizeOpts: hook for JRE-specific JAVA_OPTS (used by IBM JRE)
- installErrNote: extra context in install error messages (GraalVM)

Zing JRE is intentionally excluded — it has no memory calculator or
jvmkill and has different Finalize behaviour.

Fixes cloudfoundry#1264
DetermineJavaVersion previously returned 17 silently when the JRE release
file was missing. This made it impossible to diagnose broken or incomplete
JRE installations.

Changes:
- DetermineJavaVersion now returns an error for missing/unreadable release files
- BaseJRE.Finalize() logs a WARNING when falling back to Java 17
- Tomcat.Supply() logs a WARNING when falling back to Java 17
- Updated tests to reflect the new error behaviour
@stokpop
Copy link
Copy Markdown
Contributor Author

stokpop commented May 20, 2026

Added a follow-up commit that improves observability when the JRE release file is missing or unreadable:

  • DetermineJavaVersion now returns an error instead of silently returning 17 when the release file is absent
  • BaseJRE.Finalize() and Tomcat.Supply() both log a **WARNING** when falling back to Java 17

This means a broken or incomplete JRE installation will now produce a visible warning in buildpack output rather than silently proceeding with Java 17 assumptions.

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.

Refactor duplicate JRE implementations into shared BaseJRE struct

1 participant