- 1. Decision Index
- 2. Decisions
- 2.1. [RC-FN-001] Allow hyphenated descriptor class names
- 2.2. [RC-TEST-002] Align coverage gate with achieved baseline
- 2.3. [RC-FN-002] Cached compiler API and custom class loaders
- 2.4. [RC-NF-P-006] Performance and metaspace budget for cached compilation
- 2.5. [RC-RISK-026] Debug artefact directory safety
This log records architectural and process choices for the Java Runtime Compiler.
Each entry uses the Nine-Box tag set and links back to project-requirements.adoc where possible.
-
RC-FN-001 Allow hyphenated descriptor class names
-
RC-TEST-002 Align coverage gate with achieved baseline
-
RC-FN-002 Cached compiler API and custom class loaders
-
RC-NF-P-006 Performance and metaspace budget for cached compilation
-
RC-RISK-026 Debug artefact directory safety
-
Date: 2025-10-28
-
Context:
-
The runtime compiler recently introduced stricter validation that rejected binary names containing hyphens.
-
Java reserves
module-infoandpackage-infodescriptors, and downstream uses rely on compiling them through the cached compiler. -
We must prevent injection of directory traversal or shell-sensitive characters while honouring legitimate descriptor forms.
-
-
Decision Statement:
-
Relax the class name validation to accept hyphenated segments such as
module-infoandpackage-info, while maintaining segment level controls for other characters.
-
-
Notes/Links:
-
Change implemented in
src/main/java/net/openhft/compiler/CachedCompiler.java.
-
-
Date: 2025-10-28
-
Context:
-
The enforced JaCoCo minimums were 83 % line and 76 % branch coverage, below both the documentation target and the current test suite capability.
-
Recent test additions raise the baseline to ~85 % line and branch coverage, but still fall short of the historical 90 % goal.
-
Failing builds on the higher 90 % target blocks releases without immediate scope to add more tests.
-
-
Decision Statement:
-
Increase the JaCoCo enforcement thresholds to 85 % for line and branch coverage so the build reflects the present safety net while keeping headroom for future improvements.
-
-
Alternatives Considered:
-
Retain the 90 % requirement:
-
Pros: Preserves the original aspiration.
-
Cons: The build fails despite the current suite, causing friction for ongoing work.
-
-
Keep legacy 83/76 % thresholds:
-
Pros: No configuration change needed.
-
Cons: Enforcement would lag the actual quality level, risking future regressions.
-
-
-
Rationale for Decision:
-
Setting the guard at 85 % matches the measurable baseline and ensures regression detection without blocking releases.
-
The documentation and configuration now stay consistent, supporting future increments once more tests land.
-
-
Impact & Consequences:
-
Build pipelines now fail if coverage slips below the new 85 % thresholds.
-
Documentation for requirement JRC-TEST-014 is updated to the same value.
-
-
Notes/Links:
-
Thresholds maintained in
pom.xml. -
Updated requirement:
src/main/docs/project-requirements.adoc(JRC-TEST-014).
-
- Date
-
2025-11-14
- Context
-
-
Callers need a simple way to compile Java source from a string and obtain a
Classat runtime. -
The project requirements JRC-FN-001 to JRC-FN-004 call for a singleton cached compiler and support for custom
ClassLoaderinstances. -
Creating a new compiler for every call would waste CPU time and increase memory pressure.
-
- Decision
-
-
Use
CompilerUtils.CACHED_COMPILERas the default entry point for simple compile and load operations. -
Expose
CachedCompileras a reusable component that caches compiled classes per class loader and supports optional debug directories for.javaand.classfiles.
-
- Alternatives
- * Always construct a new
CachedCompilerinstance for each compilation. -
-
Pros: Very explicit lifecycle; no shared state.
-
Cons: Higher overhead per call and no reuse of compiled classes.
-
- * Provide only low level
CachedCompilerAPIs and no static helper. -
-
Pros: Maximum flexibility for advanced users.
-
Cons: Common call sites would need boilerplate and could easily misuse the cache.
-
- Rationale
-
-
A shared cached compiler keeps the public API small and satisfies JRC-FN-002 while allowing advanced users to manage their own instances.
-
Per class loader caching aligns with application isolation and typical container deployments.
-
- Impact
-
-
Most applications rely on the shared
CACHED_COMPILER; misuse can pin classes for the lifetime of the class loader, so long running systems should treat loader choice carefully. -
Tests must exercise both the shared singleton and user supplied
CachedCompilerinstances, including customClassLoaderpaths.
-
- Links
-
-
src/main/java/net/openhft/compiler/CompilerUtils.java -
src/main/java/net/openhft/compiler/CachedCompiler.java -
src/main/docs/project-requirements.adoc(JRC-FN-001 to JRC-FN-005)
-
- Date
-
2025-11-14
- Context
-
-
Requirements JRC-NF-P-006 to JRC-NF-P-008 set limits on compilation latency, steady state invocation overhead, and metaspace growth.
-
Initialising
JavaCompilerandStandardJavaFileManageris relatively expensive and must not be repeated unnecessarily. -
Debug output is helpful but can slow down compilation and increase disk activity.
-
- Decision
-
-
Reuse a single
JavaCompilerandStandardJavaFileManageracross compilation calls viaCompilerUtils.reset(). -
Maintain a
MyJavaFileManagerper class loader insideCachedCompilerto isolate compiled artefacts while still sharing core compiler infrastructure. -
Use a small default option set (
-g,-nowarn) and allow callers to supply additional options when constructing aCachedCompiler.
-
- Alternatives
- * Instantiate a new
JavaCompilerand file manager for every compilation. -
-
Pros: Simple to reason about; no shared mutable state.
-
Cons: Slower start up and higher CPU cost for repeated compiles.
-
- * Disable debug information and warnings by default.
-
-
Pros: Slightly faster and smaller class files.
-
Cons: Harder to debug issues and reconcile compiler output with source.
-
- Rationale
-
-
Reusing compiler infrastructure is the most effective way to keep compile times within the required budget while still supporting rich diagnostics.
-
Per class loader file managers help bound metaspace growth and keep compiled classes associated with the correct loader.
-
- Impact
-
-
First use of the compiler pays the initialisation cost; subsequent compiles should be significantly faster.
-
Long running processes that create many class loaders must still monitor metaspace usage; tests and benchmarks track these behaviours.
-
- Links
-
-
src/main/java/net/openhft/compiler/CompilerUtils.java -
src/main/java/net/openhft/compiler/CachedCompiler.java -
src/main/docs/project-requirements.adoc(JRC-NF-P-006 to JRC-NF-P-008)
-
- Date
-
2025-11-14
- Context
-
-
Requirement JRC-FN-005 mandates a debug mode that writes
.javaand.classfiles to user supplied directories. -
Requirement JRC-RISK-026 requires a retention policy and safe handling of those directories.
-
Without validation a hostile caller could attempt directory traversal using relative paths.
-
- Decision
-
-
Treat the configured source and class directories as roots and resolve all debug file paths beneath them using the
safeResolvehelper. -
Reject any path that would escape the configured root directory and throw an
IllegalArgumentExceptionwhen traversal is detected.
-
- Alternatives
- * Write files using the relative paths as supplied without extra checks.
-
-
Pros: Simpler implementation.
-
Cons: Risk of writing outside the intended directory tree.
-
- * Remove debug file emission from the library.
-
-
Pros: Eliminates this class of risk.
-
Cons: Makes troubleshooting much harder and violates JRC-FN-005.
-
- Rationale
-
-
Safe resolution of paths balances the need for useful debug output with the requirement to keep file writes constrained to explicit directories.
-
Failing fast on invalid paths helps surface configuration issues early in development and testing.
-
- Impact
-
-
Callers must choose appropriate root directories; attempts to write using paths that escape those roots will fail.
-
Future work on retention tooling should build on the same root directory assumptions.
-
- Links
-
-
src/main/java/net/openhft/compiler/CachedCompiler.java(safeResolve) -
src/main/docs/project-requirements.adoc(JRC-FN-005, JRC-RISK-026)
-