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

  1. Read the carried EspressoClassLoadingException message to find the exact verification/linkage failure.
  2. Recompile with a conforming compiler (javac or ASM with COMPUTE_FRAMES) so StackMapTable frames are regenerated, and resubmit.
  3. If a transformer agent is involved, disable it to confirm it is producing unverifiable bytecode, then fix or update the agent.
  4. 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

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.