{"record":{"id":"244b9c99ad1b6336","repo":"pinpoint-apm/pinpoint","slug":"unexpected-class-classname","errorCode":null,"errorMessage":"unexpected class ${className}","messagePattern":"unexpected class (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"agent-module/profiler-optional/profiler-optional-jdk8/src/main/java/com/navercorp/pinpoint/profiler/instrument/lambda/LambdaFactoryClassAdaptor.java","lineNumber":68,"sourceCode":"            return new LambdaClassJava15();\n        } else if (JvmUtils.getVersion().onOrAfter(JvmVersion.JAVA_9)) {\n            return new LambdaClassJava9();\n        } else {\n            return new LambdaClassJava8();\n        }\n    }\n\n    public byte[] transform(byte[] bytes, LambdaClass lambdaClass) {\n        Objects.requireNonNull(bytes, \"bytes\");\n\n        final ClassReader reader = new ClassReader(bytes);\n        final ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_FRAMES);\n        final List<MethodInsn> methodInsnList = lambdaClass.getMethodInsnList();\n        final MethodInstReplacer methodInstReplacer = new MethodInstReplacer(writer, methodInsnList);\n        reader.accept(methodInstReplacer, 0);\n\n        if (!LAMBDA_FACTORY_CLASS_NAME.equals(methodInstReplacer.getClassName())) {\n            throw new IllegalArgumentException(\"unexpected class \" + methodInstReplacer.getClassName());\n        }\n\n        if (methodInstReplacer.getTransformCount() != 1) {\n            logger.warn(\"unexpected {} invoke count {}\", methodInsnList, methodInstReplacer.getTransformCount());\n            // dump bytecode\n        }\n        return writer.toByteArray();\n    }\n}\n","sourceCodeStart":50,"sourceCodeEnd":78,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/agent-module/profiler-optional/profiler-optional-jdk8/src/main/java/com/navercorp/pinpoint/profiler/instrument/lambda/LambdaFactoryClassAdaptor.java#L50-L78","documentation":"LambdaFactoryClassAdaptor.transform rewrites the bytecode of a JVM lambda factory synthetic class, expecting the class it reads to be exactly LAMBDA_FACTORY_CLASS_NAME (java/lang/invoke/LambdaMetafactory-style). If the replaced class name differs, it throws IllegalArgumentException because the adaptor was applied to the wrong class. It also warns when the method-instruction replacement count is not exactly 1.","triggerScenarios":"ClassFileTransformer/loadTransformedBytecode matched a class name pattern that resolved to a different runtime class name than the expected lambda factory class (e.g. a lambda subclass or a differently named synthetic class under the same matcher).","commonSituations":"JDK updates changing lambda synthetic class naming; lambda proxy classes cached/reused across classloaders; overly broad transform matcher matching a non-lambda class.","solutions":["Verify the transformer's matcher targets the exact lambda factory class name for the running JDK","Update the plugin/profiler-optional-jdk8 module to a version compatible with the current JDK's lambda naming","Narrow the transform matcher so only the intended synthetic lambda class is adapted","Check the logged actual class name in the message and adjust LAMBDA_FACTORY_CLASS_NAME accordingly"],"exampleFix":"// before\nif (!LAMBDA_FACTORY_CLASS_NAME.equals(methodInstReplacer.getClassName())) {\n    throw new IllegalArgumentException(\"unexpected class \" + methodInstReplacer.getClassName());\n}\n// after\nString actual = methodInstReplacer.getClassName();\nif (!LAMBDA_FACTORY_CLASS_NAME.equals(actual) && !ALT_LAMBDA_FACTORY_CLASS_NAME.equals(actual)) {\n    logger.warn(\"skipping transform, unexpected class {}\", actual);\n    return null; // leave bytecode untouched instead of failing the transform\n}","handlingStrategy":"try-catch","validationCode":"byte[] transformed;\ntry {\n    transformed = adaptor.transform(loader, className, clazz, protectionDomain, bytecode);\n} catch (Exception e) {\n    logger.warn(\"lambda transform skipped for {}\", className, e);\n    return null; // return original bytecode\n}","typeGuard":null,"tryCatchPattern":"try {\n    return loadTransformedBytecode(lambdaClass);\n} catch (IllegalArgumentException e) {\n    logger.warn(\"unexpected class during lambda transform: {}\", e.getMessage());\n    return originalBytecode; // degrade gracefully instead of failing class loading\n}","preventionTips":["Pin the profiler/plugin version to one tested against your JDK's lambda class naming","Keep transform matchers narrow so only the intended synthetic class is adapted","Read the actual class name in the error message and compare it to LAMBDA_FACTORY_CLASS_NAME","Wrap transform calls so failures return the original bytecode rather than breaking class loading"],"tags":["lambda","bytecode","classloader","jdk"],"backgroundTag":"internal-invariant-violation","analyzedSha":"744c3d3075e595656abb1ae331ad2c0e4c9eb996","analyzedAt":"2026-09-07T18:48:45.289Z","contentChangedAt":"2026-09-07T18:48:45.289Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}