pinpoint-apm/pinpoint · error · IllegalStateException

Transformer already exist. className

Error message

Transformer already exist. className:${classInternalName} new:${transformer.getClass()} old:${old.getClass()}

What it means

addModifier0() stores transformers in a map keyed by class internal name; the registry enforces a strict one-transformer-per-class rule, throwing IllegalStateException when a second transformer tries to claim the same class. This prevents silent transformer chaining/ordering bugs.

Solutions

  1. Remove one of the duplicate plugin jars or disable one plugin targeting the class in the profiler config
  2. Ensure plugins are only loaded once (check the agent plugin directory for duplicates)
  3. Merge the two instrumentation targets into a single transformer if both must modify the class

Example fix

// before (two jars targeting the same class)
plugins: my-plugin.jar, other-plugin.jar // both target com.example.Foo
// after
plugins: my-plugin.jar // keep only one transformer per target class
Defensive patterns

Strategy: validation

Validate before calling

Set<String> claimed = new HashSet<>();
for (String cn : matcherClassNames) {
    String internal = JavaAssistUtils.javaNameToJvmName(cn);
    if (!claimed.add(internal)) throw new IllegalStateException("duplicate transformer target: " + internal);
}

Try / catch

try {
    registry.addTransformer(transformer, matcher);
} catch (IllegalStateException e) {
    logger.error("Duplicate transformer registration: {}", e.getMessage());
}

Prevention

When it happens

Trigger: Calling addTransformer() for the same target class internal name twice — e.g. two plugins instrumenting the same class, or the same plugin registered twice.

Common situations: Two Pinpoint plugins both targeting e.g. com.mysql.jdbc.Connection; duplicate plugin jar on the agent classpath; profile type config causing a base plugin and an optional plugin to load together.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


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

Appendix: source

Thrown at agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/transformer/DefaultTransformerRegistry.java:97

            final ClassNameMatcher classNameMatcher = (ClassNameMatcher) matcher;
            String className = classNameMatcher.getClassName();
            addModifier0(registry, transformer, className);
        } else if (matcher instanceof MultiClassNameMatcher) {
            final MultiClassNameMatcher classNameMatcher = (MultiClassNameMatcher) matcher;
            List<String> classNameList = classNameMatcher.getClassNames();
            for (String className : classNameList) {
                addModifier0(registry, transformer, className);
            }
        } else {
            throw new IllegalArgumentException("unsupported matcher :" + matcher);
        }
    }

    private void addModifier0(Map<String, ClassFileTransformer> registry, ClassFileTransformer transformer, String className) {
        final String classInternalName = JavaAssistUtils.javaNameToJvmName(className);
        final ClassFileTransformer old = registry.put(classInternalName, transformer);
        if (old != null) {
            throw new IllegalStateException("Transformer already exist. className:" + classInternalName + " new:" + transformer.getClass() + " old:" + old.getClass());
        }
    }
}

View on GitHub (pinned to 744c3d3075)