pinpoint-apm/pinpoint · error · IllegalStateException

Unable to set registry for AnnotationKeyProvider

Error message

Unable to set registry for AnnotationKeyProvider

What it means

TraceMetadataRegistrar.registerAnnotationKeys reflectively injects an AnnotationKeyLocator into a static field of AnnotationKeyProvider. An IllegalAccessException is wrapped in this IllegalStateException, meaning annotation keys cannot be registered and any later AnnotationKey lookup will fail. Same bootstrap-reflection failure family as the ServiceTypeProvider variant.

Source

Thrown at commons-profiler/src/main/java/com/navercorp/pinpoint/common/profiler/trace/TraceMetadataRegistrar.java:60

    }

    private TraceMetadataRegistrar() {
        throw new AssertionError();
    }

    public static void registerServiceTypes(ServiceTypeLocator serviceTypeLocator) {
        try {
            serviceTypeLocatorField.set(null, serviceTypeLocator);
        } catch (IllegalAccessException e) {
            throw new IllegalStateException("Unable to set registry for ServiceTypeProvider", e);
        }
    }

    public static void registerAnnotationKeys(AnnotationKeyLocator annotationKeyLocator) {
        try {
            annotationKeyLocatorField.set(null, annotationKeyLocator);
        } catch (IllegalAccessException e) {
            throw new IllegalStateException("Unable to set registry for AnnotationKeyProvider", e);
        }
    }
}

View on GitHub (pinned to 744c3d3075)

Solutions

  1. Align commons-profiler jar versions so TraceMetadataRegistrar and AnnotationKeyProvider match.
  2. Add --add-opens JVM flags (or downgrade/upgrade JDK) so reflection into the pinpoint package is permitted.
  3. Confirm the bootstrap sequence: the class holding the field must be initialized via the intended registrar path once, before AnnotationKeyProvider methods are used.

Example fix

// before
TraceMetadataRegistrar.registerAnnotationKeys(locator); // throws under JDK 17 strong encapsulation
// after
// JVM args: --add-opens com.navercorp.pinpoint.common.profiler.trace=ALL-UNNAMED
TraceMetadataRegistrar.registerAnnotationKeys(locator);
Defensive patterns

Strategy: try-catch

Validate before calling

boolean ok;
try {
    Class<?> c = Class.forName("com.navercorp.pinpoint.common.profiler.trace.AnnotationKeyProvider");
    Field f = c.getDeclaredField("annotationKeyLocator");
    f.setAccessible(true);
    ok = java.lang.reflect.Modifier.isStatic(f.getModifiers());
} catch (ReflectiveOperationException e) { ok = false; }
if (!ok) throw new IllegalStateException("AnnotationKeyProvider field not reflectively settable; check --add-opens/jar versions");

Try / catch

try {
    TraceMetadataRegistrar.registerAnnotationKeys(locator);
} catch (IllegalStateException e) {
    logger.error("Failed to register annotation keys", e);
    throw e;
}

Prevention

When it happens

Trigger: Calling TraceMetadataRegistrar.registerAnnotationKeys(...) when the pre-cached annotationKeyLocatorField cannot be set: caller lacks reflective access to AnnotationKeyProvider's package (JDK strong encapsulation), field is final in a changed version, or the class was loaded by a foreign classloader.

Common situations: JDK 9+ running without --add-opens for the pinpoint package; mismatched pinpoint jar versions where AnnotationKeyProvider's field layout differs; agent/app-server classloader isolation preventing access to the declaring class.

Related errors


AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07). Data as JSON: /api/errors/3de152f461de1cba. Report an issue: GitHub.