{"record":{"id":"dad74260bb7a64a8","repo":"NationalSecurityAgency/ghidra","slug":"delegate-must-implement-abstract-methods-from-all","errorCode":null,"errorMessage":"Delegate must implement abstract methods from all mixins. Missed: {method}","messagePattern":"Delegate must implement abstract methods from all mixins\\. Missed: (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/ProposedUtils/src/main/java/utilities/util/ProxyUtilities.java","lineNumber":103,"sourceCode":"\t\tprivate final Object delegate;\n\t\tprivate final MethodHandles.Lookup lookup;\n\n\t\tComposedHandler(Object delegate, MethodHandles.Lookup lookup) {\n\t\t\tthis.delegate = delegate;\n\t\t\tthis.lookup = lookup;\n\t\t}\n\n\t\t@Override\n\t\tpublic Object invoke(Object proxy, Method method, Object[] args)\n\t\t\t\tthrows Throwable {\n\t\t\t// TODO: Cache handles or pre-load them\n\t\t\tObject result;\n\t\t\tif (method.getDeclaringClass().isAssignableFrom(delegate.getClass())) {\n\t\t\t\tMethodHandle handle = lookup.unreflect(method);\n\t\t\t\tresult = handle.bindTo(delegate).invokeWithArguments(args);\n\t\t\t}\n\t\t\telse if (!method.isDefault()) {\n\t\t\t\tthrow new IllegalStateException(\n\t\t\t\t\t\"Delegate must implement abstract methods from all mixins. Missed: \" + method);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tMethodHandle mh = getSuperMethodHandle(method, lookup);\n\t\t\t\tresult = mh.bindTo(proxy).invokeWithArguments(args);\n\t\t\t}\n\t\t\t/**\n\t\t\t * NOTE: I cannot replace the delegate with the proxy here (say, to prevent accidental\n\t\t\t * leakage) for at least two reasons. 1) I may want direct access to the delegate. 2) It\n\t\t\t * wouldn't work when the return value itself wraps or will provide the delegate (e.g.,\n\t\t\t * a future).\n\t\t\t */\n\t\t\treturn result;\n\t\t}\n\t}\n}\n","sourceCodeStart":85,"sourceCodeEnd":120,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/ProposedUtils/src/main/java/utilities/util/ProxyUtilities.java#L85-L120","documentation":"ProxyUtilities builds a dynamic proxy that weaves a delegate together with one or more mixin interfaces. When invoke is dispatched to a method that is NOT declared on the delegate's class and NOT a default method on an interface, the delegate is missing that implementation, so IllegalStateException is thrown. In short: every abstract method of every mixin must be implemented by the delegate (or be a default method).","triggerScenarios":"createProxy(delegate, MixinA.class, MixinB.class, ...) where the delegate's class does not implement some abstract method declared by a mixin interface (and that method is not a Java default method).","commonSituations":"Adding a new abstract method to a mixin interface without updating delegates; passing a delegate of a supertype that lacks the method; refactoring mixins so a previously-default method becomes abstract.","solutions":["Implement the named abstract method on the delegate class.","Add a `default` implementation to the mixin interface if appropriate.","Pass a delegate whose type already implements all the mixin interfaces."],"exampleFix":"// before\nclass MyDelegate implements ReadMixin { /* missing op() from OpMixin */ }\nObject p = ProxyUtilities.createProxy(new MyDelegate(), ReadMixin.class, OpMixin.class);\n// after\nclass MyDelegate implements ReadMixin, OpMixin {\n    @Override public void op() { /* ... */ }\n}\nObject p = ProxyUtilities.createProxy(new MyDelegate(), ReadMixin.class, OpMixin.class);","handlingStrategy":"validation","validationCode":"for (Class<?> mixin : mixins) {\n    for (Method m : mixin.getMethods()) {\n        if (!Modifier.isDefault(m.getModifiers()) &&\n            !Arrays.asList(delegate.getClass().getMethods()).toString().contains(m.getName())) {\n            // check more precisely that delegate implements m's signature\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Make the delegate's class implement all mixin interfaces so the compiler enforces coverage.","Prefer default methods on interfaces for optional mixin behavior."],"tags":["proxy","reflection","mixins","configuration"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}