oracle/graal · error · RedefinitionException
FailsVerification
FailsVerification
Error message
{} What it means
RedefinitionException with RedefinitionError.FailsVerification thrown at the end of the redefinition flow when defining the new class version raises an EspressoClassLoadingException (verification/linkage failure); the exception message is passed through. Note the sibling catch arms: plain EspressoException maps to InvalidClassFormat and ClassCircularityError to CircularClassDefinition, so this code specifically means the class parsed but failed loading/verification.
Source
Thrown at espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/redefinition/ClassRedefinition.java:456
ObjectKlass newKlass = classRegistry.defineKlass(context, type, classInfo.getBytes());
assert newKlass != loadedKlass && newKlass == classRegistry.findLoadedKlass(context.getClassLoadingEnv(), type);
packet.info.setKlass(newKlass);
} else if (classInfo.isNewInnerTestKlass()) {
// New inner test classes cannot be loaded because they'll
// have a versioned name on disk, so let's define them directly
classRegistry.defineKlass(context, type, classInfo.getBytes());
}
return;
}
} catch (EspressoException ex) {
// TODO(Gregersen) - return appropriate error code based on the exception type
// we get from parsing the class file
throw new RedefinitionException(RedefinitionError.InvalidClassFormat);
} catch (EspressoClassLoadingException.ClassCircularityError e) {
throw new RedefinitionException(RedefinitionError.CircularClassDefinition);
} catch (EspressoClassLoadingException e) {
throw new RedefinitionException(RedefinitionError.FailsVerification, e.getMessage());
}
}
// detect all types of class changes, but return early when a change that require arbitrary
// changes
private static ClassChange detectClassChanges(ParserKlass newParserKlass, ObjectKlass oldKlass, DetectedChange collectedChanges, ParserKlass finalParserKlass, boolean jvmtiRestrictions)
throws RedefinitionException {
if (oldKlass.getSuperKlass() == oldKlass.getMeta().java_lang_Enum) {
detectInvalidEnumConstantChanges(newParserKlass, oldKlass);
}
ConstantPool oldConstantPool = oldKlass.getConstantPool();
ConstantPool newConstantPool = newParserKlass.getConstantPool();
// detect invalid attribute changes for jvmti restrictions
if (jvmtiRestrictions) {
if (attrChanged(oldKlass.getAttribute(NestHostAttribute.NAME), newParserKlass.getAttribute(NestHostAttribute.NAME), oldConstantPool, newConstantPool)) {
throw new RedefinitionException(RedefinitionError.ClassAttributeChanged);
}
if (attrChanged(oldKlass.getAttribute(NestMembersAttribute.NAME), newParserKlass.getAttribute(NestMembersAttribute.NAME), oldConstantPool, newConstantPool)) {View on GitHub (pinned to a66e9ccd1d)
Solutions
- Read the carried EspressoClassLoadingException message to find the exact verification/linkage failure.
- Recompile with a conforming compiler (javac or ASM with COMPUTE_FRAMES) so StackMapTable frames are regenerated, and resubmit.
- If a transformer agent is involved, disable it to confirm it is producing unverifiable bytecode, then fix or update the agent.
- Verify that any signature changes in the new version are consistent with already-loaded dependent classes, or reload those dependents too.
Example fix
// before: ASM-generated method without frames cw.visit(Opcodes.V1_8, flags, name, null, "java/lang/Object", null); // ... emit method with jumps but no StackMapTable // after: let ASM compute frames ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
Defensive patterns
Strategy: try-catch
Try / catch
catch (RedefinitionException e) {
if (e.getError() == RedefinitionError.FailsVerification) {
// e.getMessage() carries the verification error; fix bytecode/frames and resubmit
}
} Prevention
- Generate bytecode with COMPUTE_FRAMES so StackMapTable is always correct.
- Verify replacement classes by loading them in a scratch class loader first.
- Keep signature changes consistent across all classes in a hotswap batch.
When it happens
Trigger: Redefining a class whose new bytecode fails Espresso's verifier (bad stack shapes, incompatible method descriptors across the change, missing StackMapTable) or whose linkage fails while defining the new version in the ClassRegistry (e.g. defineKlass during schema-change handling).
Common situations: Incremental compilers or instrumentation agents generating bytecode without proper stack-map frames; redefinition bytes that violate verifier constraints for the changed method bodies; partial recompiles where a dependent class's new signature breaks linkage of the redefined class.
Related errors
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/28dbe029699a6f02.
Report an issue: GitHub.