Skip to content

Conversation

@peter-lawrey
Copy link
Member

@peter-lawrey peter-lawrey commented Nov 19, 2025

Build and dependency management

  • Bump third-party BOM

    • net.openhft:third-party-bom from 3.27ea53.27ea7, pulling in the latest curated dependency set for Chronicle-Core.
  • JetBrains annotations exposed at compile scope

    • org.jetbrains:annotations now has <scope>compile</scope> so downstream consumers see the nullability annotations on Chronicle-Core APIs without having to add the dependency themselves.

Chronicle init & system properties

  • ChronicleInit no-op hook removed from Jvm.init()

    • ChronicleInit.init() (a no-op extension hook) is removed from Jvm.init(). Static initialisation now relies solely on ChronicleInit’s static block and ChronicleInit.postInit(), which are still invoked from Jvm’s static initialiser.

    • New test harness (SystemPropertiesPrimingRunnable, SystemPropertiesProbeMain, extended ChronicleInitTest) verifies:

      • chronicle.init.runnable can prime Jvm.SYSTEM_PROPERTIES before Jvm loads system.properties.
      • chronicle.postinit.runnable can adjust runtime flags (for example jvm.resource.tracing) and that misconfiguration leads to explicit non-zero exit codes.
  • Bootstrap/Jvm construction semantics tightened

    • Bootstrap gets an explicitly deprecated public constructor (@Deprecated(/* make private in 2026 */)), signalling future encapsulation while preserving current behaviour.
    • ChronicleInit’s constructor is moved below the static block, but remains private and purely for non-instantiability.

IO, filesystem and process handling

  • More robust file IO using NIO APIs

    • Jvm.loadSystemProperties now uses Files.newInputStream(file.toPath()) instead of new FileInputStream, aligning with NIO and centralising resource handling.
    • IOTools.writeFile now uses Files.newOutputStream(Paths.get(filename)), keeping semantics (including .gz handling) while improving error propagation.
    • LicenceCheck reads <product>.expiry-date explicitly as UTF-8 (new String(..., UTF_8)), removing platform-default charset ambiguities for licence expiry checks.
  • Tmp/target directory creation with warnings instead of silent failure

    • OS.findTmp0() and OS.findTarget0() now:

      • Check whether mkdir()/mkdirs() succeed; if not, they log a warning via Jvm.warn().on(OS.class, ...) instead of silently continuing with a potentially unusable path.
      • Fall back to "tmp" or ${java.io.tmpdir}/target but emit a warning if directory creation fails.
  • PID and process utilities hardened

    • OS.getProcessId0() now uses ThreadLocalRandom instead of SecureRandom when falling back to a random PID, avoiding blocking entropy sources in constrained environments.

    • Jvm.isProcessAlive0(long pid, String command):

      • Now uses StandardCharsets.UTF_8 when reading subprocess output.
      • Ensures the Process is always destroyed in a finally block.
      • Continues to treat “command invocation failure” as “assume process alive” to preserve existing behaviour.
    • OS.run(String... cmds):

      • Uses UTF-8 for decoding the subprocess output.
      • Always destroys the spawned process in a finally block.
  • Memory mapping and unmapping diagnostics

    • OS.unmap(long address, long size, int pageSize) now captures the native return code from unmapp0 and, when debug logging is enabled, logs non-zero results together with the affected address.
    • Behaviour on success/failure is otherwise unchanged; errors still rethrow as IOException.

Signal handling, logging and exception infrastructure

  • SLF4J parameterised logging upgrades

    • Several string-concatenation logging calls have been converted to SLF4J’s {} style, for example:

      • Jvm startup logging: "Chronicle core loaded from {}" instead of String.format(...).
      • CpuClass warnings when wmic/sysctl fail: "process {} returned {}" and "process {} waitFor threw " with the command and return code injected.
      • ChainedExceptionHandler now logs "Unable to call with message {}" instead of string concatenation.
  • ExceptionKey message fallback semantics

    • ExceptionKey.message() now returns throwable.toString() when the stored message is null or empty, ensuring the key always has a meaningful description even when callers log a null message.
  • Direct buffer and IO utilities

    • DirectBufferUtil.addressOrThrow(ByteBuffer):

      • Now explicitly checks instanceof DirectBuffer, throwing a ClassCastException with a descriptive message if invoked on a non-direct buffer.
      • Previously, some misuses could manifest as IllegalAccessError or other lower-level errors; behaviour is now clearer and more predictable.
    • Wget.fetch():

      • Ensures the Reader created around the limited stream is closed via try-with-resources.
      • Deprecated the convenience Wget.url(String, StringBuilder) and builder customisation methods for tests, while keeping runtime behaviour unchanged.
      • The size-limit enforcement via LimitedInputStream is unchanged; tests now assert its semantics more explicitly.
    • LimitedInputStream:

      • Throws IllegalArgumentException at construction for negative size limits.
      • For bulk reads, consumes as much as possible up to the budget in a single call and then, on subsequent reads, throws a clear "Size limit exceeded" IOException if underlying data remains.

Core utilities and behaviour fixes

  • GenericReflection.erase(Type)

    • Now:

      • Handles ParameterizedType by erasing to the raw type (unchanged).
      • Continues to accept Class instances.
      • Explicitly throws UnsupportedOperationException for unsupported Type flavours instead of a potentially unsafe cast; tests cover realistic usages and no production callers should hit the new exception path.
  • Maths.divideRoundUp(long, long)

    • Javadoc updated; behaviour unchanged (still throws ArithmeticException on zero divisor). The test is corrected to actually assert the exception rather than calling the method unguarded.
  • ObjectUtils / StringUtils small semantic tweaks

    • ObjectUtils.getAllInterfaces(Object) now uses toArray(new Class<?>[0]) instead of pre-sizing from size(), which is semantically equivalent but favours the recommended idiom.
    • ObjectUtils.requireNonNull is centralised and tested; semantics unchanged (still uses the o.getClass() trick).
    • StringUtils.newStringFromBytes(byte[]) now uses new String(bytes, ISO_8859_1) when one-byte-per-char is not available, and a new String(new byte[0], ISO_8859_1) placeholder for the reflection path (behaviourally equivalent, but avoids the “redundant String constructor” pattern).
    • StringUtils.extractBytes(String) and tests now consistently use ISO_8859_1/UTF-8 via constants instead of implicit platform defaults.
  • Licence/expiry handling

    • LicenceCheck.licenceExpiry reads *.expiry-date using UTF-8, making licence expiry checks deterministic across locales/filesystems.

Deprecations and future removals

This PR adds deprecation markers (with target removal years) on a set of legacy or test-only APIs to make the roadmap explicit while preserving binary compatibility:

  • Runtime/developer APIs (2027 unless noted):

    • Jvm:

      • isJava12Plus() (test-only)
      • isFlightRecorder()
      • lockWithStack(ReentrantLock)
      • usedDirectMemory(), usedNativeMemory() (test-only)
      • setThreadLocalExceptionHandlers(...) overload with 6 args
      • areOptionalSafepointsEnabled() (test-only)
      • stackTraceEndsWith(String, int)
      • classMetrics(Class<?>) (test-only)
      • userHome()
    • OS:

      • findDir(String), getIPAddress(), getUserDir(), getPidMax(), map(FileChannel, MapMode, start, size), spaceUsed(String), userDir() – marked for eventual removal or consolidation into newer APIs; tests use them explicitly.
    • UnsafeMemory:

      • IS_LITTLE_ENDIAN constant and several static helpers (putInt(byte[],...), unsafeStoreFence(), unsafePutLong(...), unsafePutInt(...), unsafePutByte(...)) – retained for compatibility, signposted for removal or replacement with the Memory interface.
    • Maths.roundNup(double, int) – deprecated in favour of the more predictable roundN.

    • ForceInline and HotMethod annotations – deprecated, retained only for legacy benchmark tooling.

    • RangeUtil and many assertion/invariant helpers (Ints.assertIfEnabled, Ints.nonNegative, etc.) – visible deprecations ahead of API simplification.

    • AbstractCloseable.gcAndWaitForCloseablesToClose(), AbstractCloseableReferenceCounted.throwExceptionIfClosedInSetter() – still wired through but marked as legacy.

    • LimitedInputStream – now explicitly deprecated and documented as test-only; public callers should use higher-level APIs (e.g. Wget or caller-specific wrappers).

    • ThreadLocalHelper.getSTL(...), ClassMetrics, CompilerUtils, RecordingHistogram.typical(), SerializableUpdaterWithArg, StringUtils.set(...), StringUtils.newStringFromBytes(...), StringUtils.toTitleCase, StringUtils.parseLong(...), MaxBytes – flagged as test-only or legacy support and scheduled for removal.

  • Chronicle cooler/cpu utilities:

    • CoolerTester and CpuCoolers are annotated with TODOs to move into Chronicle-Test-Framework in 2026 and include a sentinel check on the blackhole to catch misuse.

All deprecations preserve current behaviour; no methods have been removed in this PR.


Non-functional changes

Code quality and style

  • Switch more tests and utilities to UTF-8 / ISO-8859-1 explicitly (tests updated accordingly).

  • Replace ad-hoc fail()/try/catch patterns with assertThrows(...) and JUnit 5 assertions where appropriate.

  • Remove unused fields and dead code (e.g. inner classes that existed only for tests or experimental code), and drop an unused jitter harness (LongPingPongMain).

  • Consistently move static holder classes to the bottom of files and make their constructors private.

  • Improve test robustness around:

    • temporary directory creation and recursive deletion with checked error handling,
    • concurrency tests for BackgroundResourceReleaser, CleaningThreadLocal, ScopedThreadLocal, and UniqueMicroTimeProvider,
    • service-loader and cleaner SPI error paths (priority, mixed valid/invalid entries, ServiceConfigurationError fallback),
    • Chronicle init exit codes and resource-tracing toggles.

Logging and diagnostics

  • Improve error messages and stack-trace expectations in tests to accommodate JVM version differences (e.g. StackTrace and Thread naming in Java 20+).
  • Add new reference-tracing integration tests to validate ReferenceCountedUtils when tracing is enabled and ensure leak diagnostics include suppressed StackTrace snapshots.

@peter-lawrey peter-lawrey changed the title Remove unused imports and improve code readability in test classes Tightens Chronicle Core’s documentation, encoding handling and init/tracing behaviour Nov 19, 2025
@peter-lawrey peter-lawrey changed the title Tightens Chronicle Core’s documentation, encoding handling and init/tracing behaviour Document Chronicle-Core architecture and tighten init/IO/process handling Nov 24, 2025
@sonarqubecloud
Copy link

@peter-lawrey peter-lawrey changed the base branch from develop to adv/javadoc December 1, 2025 13:23
# Conflicts:
#	src/main/java/net/openhft/chronicle/core/internal/util/RangeUtil.java
#	src/main/java/net/openhft/chronicle/core/io/Wget.java
#	src/test/java/net/openhft/chronicle/core/UnsafePingPointMain.java
#	src/test/java/net/openhft/chronicle/core/cleaner/CleanerServiceFallbackTest.java
#	src/test/java/net/openhft/chronicle/core/onoes/ChainedExceptionHandlerTest.java
#	src/test/java/net/openhft/chronicle/core/util/AbstractInvocationHandlerTest.java
#	src/test/java/net/openhft/chronicle/core/util/CompilerUtilsTest.java
@peter-lawrey peter-lawrey changed the title Document Chronicle-Core architecture and tighten init/IO/process handling Deprecate legacy Chronicle-Core APIs, harden IO/process utilities, and align tests with new init/analytics semantics Dec 1, 2025
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.

3 participants