Debugging JaCoCo‑Induced ClassCastException Caused by Synthetic $jacocoData Field in Java

The article explains how integrating JaCoCo introduced a synthetic boolean array field ($jacocoData) that caused a ClassCastException during object encryption, analyzes the root cause by inspecting bytecode and reflection, and provides a fix by filtering synthetic fields using isSynthetic().

JD Tech Talk
JD Tech Talk
JD Tech Talk
Debugging JaCoCo‑Induced ClassCastException Caused by Synthetic $jacocoData Field in Java

Problem Description – After adding JaCoCo to a Java project, the application started normally but threw a

java.lang.ClassCastException: [Z cannot be cast to [Ljava.lang.Object;

during order processing, blocking the workflow. The stack trace pointed to the encryptObject method where an object was cast to Object[].

Analysis

1. Error Code – The exception occurs because the method attempts to iterate over an object assumed to be an array of Object. The type "[Z" represents a boolean array in Java bytecode, which appears after JaCoCo instrumentation adds a synthetic field $jacocoData of type boolean[].

2. Root Cause Path – The recursive encryptObject method processes collections and arrays. When it encounters the synthetic boolean array, the cast to Object[] fails, leading to the exception. The helper method getDeclaredFieldsAll returns all fields, including synthetic ones, so the synthetic field is inadvertently processed.

3. Synthetic Fields & JaCoCo – Java compilers generate synthetic fields/methods (e.g., $jacocoData) to support features like inner‑class access. JaCoCo uses ASM to insert probe booleans into a synthetic array, which is not part of the business model.

public void encryptObject(Object obj, String type) throws IllegalAccessException {
    // ...
    if (clazz.isArray()) {
        for (Object o : (Object[]) obj) { // <-- ClassCastException here when obj is boolean[]
            this.encryptObject(o, type);
        }
    }
    // ...
}

Solution – Filter out synthetic fields before processing them. Using Field.isSynthetic() removes the JaCoCo‑added $jacocoData field, preventing the faulty cast.

List<Field> fieldsList = Arrays.stream(declaredFields)
    .filter(field -> !field.isSynthetic())
    .collect(Collectors.toList());

After applying this change and redeploying with JaCoCo enabled, the order‑processing flow works correctly.

Conclusion – The article documents a real‑world debugging case where JaCoCo instrumentation introduced a synthetic boolean array that broke reflection‑based encryption logic. Understanding compiler‑generated synthetic members and guarding against them (e.g., via isSynthetic()) improves tool robustness and prevents similar runtime failures.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JaCoCoClassCastExceptionSyntheticFields
JD Tech Talk
Written by

JD Tech Talk

Official JD Tech public account delivering best practices and technology innovation.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.