{"record":{"id":"21dc85d35f3981d6","repo":"oracle/graal","slug":"new-loading-constraint-violates-an-older-one","errorCode":null,"errorMessage":"New loading constraint violates an older one!","messagePattern":"New loading constraint violates an older one!","errorType":"exception","errorClass":"LoadingConstraintViolationException","httpStatus":null,"severity":"error","filePath":"espresso-shared/src/com.oracle.truffle.espresso.shared/src/com/oracle/truffle/espresso/shared/constraints/LoadingConstraintsShared.java","lineNumber":254,"sourceCode":"                if (!exists(c1.klass)) {\n                    c1.klass = klass;\n                }\n            } else {\n                mergeConstraints(bucket, c1, c2);\n            }\n        }\n    }\n\n    private ConstraintBucket<Loader, Storage> lookup(Symbol<Type> type) {\n        return pairings.get(type);\n    }\n\n    private long checkConstraint(long klass, Constraint<Loader, Storage> c1) throws LoadingConstraintViolationException {\n        if (c1 != null) {\n            if (exists(c1.klass)) {\n                if (exists(klass)) {\n                    if (klass != c1.klass) {\n                        throw new LoadingConstraintViolationException(\"New loading constraint violates an older one!\");\n                    }\n                } else {\n                    return c1.klass;\n                }\n            } else {\n                c1.klass = klass;\n            }\n        }\n        return klass;\n    }\n\n    private void mergeConstraints(ConstraintBucket<Loader, Storage> bucket, Constraint<Loader, Storage> c1, Constraint<Loader, Storage> c2) {\n        assert Thread.holdsLock(bucket);\n        Constraint<Loader, Storage> merge;\n        Constraint<Loader, Storage> delete;\n        if (c1.loaders.length < c2.loaders.length) {\n            merge = c2;\n            delete = c1;","sourceCodeStart":236,"sourceCodeEnd":272,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/espresso-shared/src/com.oracle.truffle.espresso.shared/src/com/oracle/truffle/espresso/shared/constraints/LoadingConstraintsShared.java#L236-L272","documentation":"While merging/registering loading constraints, LoadingConstraintsShared.checkConstraint detects that an existing constraint for a type symbol is already bound to a loaded class (c1.klass) and the new constraint names a different loaded class. Because both classes exist and differ, the new constraint contradicts the recorded one and LoadingConstraintViolationException is thrown.","triggerScenarios":"A second cross-loader operation reuses a Symbol<Type> whose constraint bucket already resolved to class A, while the new call site resolves the same name to class B (both loaded). Typical with several loaders resolving constrained method signatures inconsistently.","commonSituations":"Partial redeployment where one loader keeps the old class and a new loader loads an incompatible new version; duplicated classes across sibling loaders that later interact through constrained method calls.","solutions":["Ensure the type named in the failing constraint is loaded by a single common loader (or a common parent) across all loaders involved.","Undeploy/drop the loader holding the stale class so the old constraint's class can be garbage-collected before reloading.","Audit for duplicate jars/classes across deployment units and remove the duplicates.","Wrap the triggering call in a catch of the resulting LinkageError and report which loader pair conflicted."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    reloadedOperation();\n} catch (LinkageError e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"violates an older one\")) {\n        // old constraint still bound to a stale class: force context restart\n        scheduleContextRestart();\n    } else {\n        throw e;\n    }\n}","preventionTips":["Avoid partial redeployments that leave old and new versions of a class loaded in sibling loaders.","Design loader topology so constrained types resolve to one canonical class.","Log the type symbol and loader pair when constraints fail to speed up classpath deduplication."],"tags":["jvm","classloading","espresso","linkage","constraints"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}