{"record":{"id":"efad35f67a71e0dd","repo":"oracle/graal","slug":"invalidclassformat","errorCode":"InvalidClassFormat","errorMessage":"{}","messagePattern":"\\{\\}","errorType":"error_code","errorClass":"RedefinitionException","httpStatus":null,"severity":"error","filePath":"espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/redefinition/ClassRedefinition.java","lineNumber":235,"sourceCode":"            ParserKlass parserKlass;\n            ParserKlass newParserKlass = null;\n            ClassChange classChange;\n            DetectedChange detectedChange = new DetectedChange();\n            StaticObject loader = klass.getDefiningClassLoader();\n            TypeSymbols typeSymbols = klass.getContext().getTypes();\n            try {\n                parserKlass = ParserKlassProvider.parseKlassWithHostErrors(ClassRegistry.ClassDefinitionInfo.EMPTY, context.getClassLoadingEnv(), loader,\n                                typeSymbols.fromClassNameEntry(hotSwapInfo.getName()), bytes);\n                if (hotSwapInfo.isPatched()) {\n                    byte[] patched = hotSwapInfo.getPatchedBytes();\n                    newParserKlass = parserKlass;\n                    // we detect changes against the patched bytecode\n                    parserKlass = ParserKlassProvider.parseKlassWithHostErrors(ClassRegistry.ClassDefinitionInfo.EMPTY, context.getClassLoadingEnv(), loader,\n                                    typeSymbols.fromClassNameEntry(hotSwapInfo.getNewName()),\n                                    patched);\n                }\n            } catch (ValidationException | ParserException.ClassFormatError validationOrBadFormat) {\n                throw new RedefinitionException(RedefinitionError.InvalidClassFormat, validationOrBadFormat.getMessage());\n            } catch (ParserException.UnsupportedClassVersionError unsupportedClassVersionError) {\n                throw new RedefinitionException(RedefinitionError.UnsupportedVersion, unsupportedClassVersionError.getMessage());\n            } catch (ParserException.NoClassDefFoundError noClassDefFoundError) {\n                // see HotSpot VM_RedefineClasses::load_new_class_versions\n                throw new RedefinitionException(RedefinitionError.NamesDontMatch, noClassDefFoundError.getMessage());\n            } catch (ParserException parserException) {\n                throw EspressoError.shouldNotReachHere(\"Not a validation nor parser exception\", parserException);\n            }\n            classChange = detectClassChanges(parserKlass, klass, detectedChange, newParserKlass, jvmtiRestrictions);\n            if (classChange == ClassChange.CLASS_HIERARCHY_CHANGED && detectedChange.getSuperKlass() != null) {\n                // keep track of unhandled changed super classes\n                ObjectKlass superKlass = detectedChange.getSuperKlass();\n                ObjectKlass oldSuperKlass = klass.getSuperKlass();\n                ObjectKlass commonSuperKlass = (ObjectKlass) oldSuperKlass.findLeastCommonAncestor(superKlass);\n                while (superKlass != commonSuperKlass) {\n                    superClassChanges.add(superKlass);\n                    superKlass = superKlass.getSuperKlass();\n                }","sourceCodeStart":217,"sourceCodeEnd":253,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/redefinition/ClassRedefinition.java#L217-L253","documentation":"Thrown as RedefinitionException with RedefinitionError.InvalidClassFormat when Espresso's class redefinition (hotswap) pipeline fails to parse the new class bytes: ParserKlassProvider raised a ValidationException or ParserException.ClassFormatError. The '{}' message is the underlying parser message describing the malformed structure. Redefinition aborts before any class changes are applied.","triggerScenarios":"Calling the redefinition/hotswap API with byte[] that is not a structurally valid class file (truncated bytes, corrupted constant pool, bad magic/major version layout, instrumented bytecode from a broken agent); redefining a patched class whose patched bytes are invalid.","commonSituations":"Hotswap agents (JRebel-style tools, debuggers, custom instrumentation) producing corrupt or partially-written class files; reading class bytes from a stream that was closed early; a bytecode transformer bug injecting invalid attributes; file-transfer corruption of .class files.","solutions":["Inspect the exception message (formatted into the RedefinitionException) to identify the exact parse/verification problem.","Regenerate the class bytes with a known-good compiler or verified bytecode tool (javac, ASM with COMPUTE_FRAMES) and retry the redefinition.","Validate the bytes before submitting: parse them with a standalone class-file parser (e.g. ASM ClassReader) to confirm they are well formed.","If a patcher/instrumentation agent produced the bytes, disable it or fix its transformer to isolate the source of corruption."],"exampleFix":"// before\nbyte[] bytes = Files.readAllBytes(Paths.get(\"NewVersion.class\")); // possibly corrupt\nredefinition.redefine(klass, bytes);\n// after\nbyte[] bytes = Files.readAllBytes(Paths.get(\"NewVersion.class\"));\ntry { new org.objectweb.asm.ClassReader(bytes); } // fail fast on malformed bytes\ncatch (RuntimeException e) { throw new IllegalArgumentException(\"bad class file\", e); }\nredefinition.redefine(klass, bytes);","handlingStrategy":"validation","validationCode":"// sanity-parse replacement bytes before submitting them for redefinition\ntry {\n    new org.objectweb.asm.ClassReader(bytes).accept(null, 0);\n} catch (RuntimeException e) {\n    throw new IllegalArgumentException(\"malformed class file: \" + e.getMessage(), e);\n}","typeGuard":null,"tryCatchPattern":"catch (RedefinitionException e) {\n    if (e.getError() == RedefinitionError.InvalidClassFormat) {\n        // report, keep old class version running, regenerate bytes\n    }\n}","preventionTips":["Always round-trip generated bytecode through a parser before hotswap.","Write class bytes atomically (temp file + rename) to avoid truncated reads.","Pin bytecode tool versions so transformers stay consistent."],"tags":["espresso","hotswap","class-redefinition","bytecode","class-format"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}