{"record":{"id":"5d3bb211867dbca5","repo":"oracle/graal","slug":"unsupportedversion","errorCode":"UnsupportedVersion","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":237,"sourceCode":"            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                }\n            }\n            ChangePacket packet = new ChangePacket(hotSwapInfo, newParserKlass != null ? newParserKlass : parserKlass, classChange, detectedChange);","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/redefinition/ClassRedefinition.java#L219-L255","documentation":"RedefinitionException with RedefinitionError.UnsupportedVersion raised during hotswap when parsing the new class bytes throws ParserException.UnsupportedClassVersionError — the class file's major version is newer than what this Espresso runtime can read. The '{}' carries the parser's message (e.g. the unsupported major version number).","triggerScenarios":"Redefining a class with bytes compiled by a newer JDK than the Espresso runtime supports (e.g. class file major 65+ submitted to a runtime that caps below that); tools emitting --release flags targeting a newer bytecode level.","commonSituations":"Team members on different JDK versions: one compiles with JDK 21 while the GraalVM/Espresso runtime is 17-based; build systems whose target/release settings drifted after a JDK upgrade; CI producing artifacts with a newer default bytecode level than production.","solutions":["Recompile the new class version with a lower bytecode target supported by the runtime (javac --release <supported-version>) and retry.","Upgrade the GraalVM/Espresso runtime to a version that supports the class file version you need.","Pin the project's maven.compiler.release / --release flag to the runtime-supported version so builds stay compatible."],"exampleFix":"// before: compiled with JDK 21 -> major 65\n<properties><maven.compiler.source>21</maven.compiler.source></properties>\n// after: pin to the runtime's supported version\n<properties><maven.compiler.release>17</maven.compiler.release></properties>","handlingStrategy":"validation","validationCode":"// check the major version embedded in the bytes before redefining\nint major = ((bytes[6] & 0xFF) << 8) | (bytes[7] & 0xFF);\nif (major > MAX_SUPPORTED_MAJOR) {\n    throw new IllegalArgumentException(\"class file major \" + major + \" exceeds supported \" + MAX_SUPPORTED_MAJOR);\n}","typeGuard":null,"tryCatchPattern":"catch (RedefinitionException e) {\n    if (e.getError() == RedefinitionError.UnsupportedVersion) { /* recompile with lower --release and retry once */ }\n}","preventionTips":["Pin maven.compiler.release / javac --release to the runtime-supported version.","Fail CI when artifacts contain class versions above the production runtime's cap.","Upgrade GraalVM and guest JDK together, never independently."],"tags":["espresso","hotswap","class-redefinition","class-version","bytecode"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}