Skip to content
Community

EXPLORE TOPICS

Editorial approach

New to CoreTrailKit?

Observe your services. Keep the evidence close.

CoreTrailKit
Back to articles
GUIDE/ Java

Java reflection: fix inaccessible JDK access

An application upgrade exposes InaccessibleObjectException while a helper tries to inspect a private JDK field. The helper may rely on an internal representation that the runtime does not open for reflective access.

By CoreTrailKit3 min read

01

Read the module-access error and call stack

Capture the declaring module, package, requested member, and the application or library method attempting access. A runtime enforcing access rules is a different failure from a missing field or class.

Our fixture called String.class.getDeclaredField("value") and then setAccessible(true). On the tested JDK it raised InaccessibleObjectException because the required private access was not enabled. It did not reveal a portable contract for String’s storage.

02

Identify whether the application or a dependency owns the access

If a library performs the reflection, check its documented support for the chosen JDK and update through the application’s normal dependency process. A change to your own helper cannot repair a separate incompatible dependency still loaded elsewhere.

If you own the helper, write down why it accesses the internals. For our example, the desired output was UTF-8 bytes for a text payload. Reading String’s private backing field is not the documented way to produce that encoding.

03

Replace the specific operation with a public API

Save this tested text-encoding example as PublicStringEncoding.java. It uses the specified UTF-8 charset and checks the exact encoded bytes and decoded text. It does not access String internals.

This changes the implementation to an explicit encoding contract. It should not be described as exposing the same private buffer: a JDK’s internal representation is not the external UTF-8 representation guaranteed by this code.

java · EXAMPLE
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

public class PublicStringEncoding {
    public static void main(String[] args) {
        String text = "café";
        byte[] utf8 = text.getBytes(StandardCharsets.UTF_8);
        if (!text.equals(new String(utf8, StandardCharsets.UTF_8))) {
            throw new AssertionError("UTF-8 round trip failed");
        }
        byte[] expected = {99, 97, 102, (byte) 0xc3, (byte) 0xa9};
        if (!Arrays.equals(utf8, expected)) throw new AssertionError("Wrong bytes");
        System.out.println("public API round trip=" + text);
    }
}

04

Run the replacement under ordinary module boundaries

Compile and run without adding package-opening flags. The fixture printed public API round trip=café and verified the five expected UTF-8 bytes for that text.

For a real serialization or persistence library, test the actual supported integration path. A small String example cannot prove that an arbitrary library version is compatible with the entire JDK.

sh · EXAMPLE
javac -encoding UTF-8 -d out PublicStringEncoding.java
java -cp out PublicStringEncoding

05

Treat migration flags as a separate decision

A narrowly documented compatibility flag can be part of a temporary migration plan for a specific dependency, but it changes access boundaries rather than correcting that dependency’s reliance on internals. Review its exact scope and support status before adopting it.

Our correction needed no module-opening flags. Keep the failing caller, selected library/runtime versions, replacement contract, and verification result together so a later upgrade does not accidentally restore the unsupported access.

Know the limits

Reproduced with Eclipse Temurin OpenJDK 25.0.4.1+1 in a disposable Linux container with no external network. Reflective access to String.value failed under the default module boundaries. A public UTF-8 encoding and decoding operation passed with expected bytes. This is a specific text-encoding replacement, not a general replacement for every reflection-based library or framework.

Sources & further reading

A technical publication by CoreTrailKit.

Browse all articles

CONTINUE EXPLORING