NationalSecurityAgency/ghidra · error · IllegalStateException

Delegate must implement abstract methods from all mixins. Mi

Error message

Delegate must implement abstract methods from all mixins. Missed: {method}

What it means

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).

Source

Thrown at Ghidra/Debug/ProposedUtils/src/main/java/utilities/util/ProxyUtilities.java:103

		private final Object delegate;
		private final MethodHandles.Lookup lookup;

		ComposedHandler(Object delegate, MethodHandles.Lookup lookup) {
			this.delegate = delegate;
			this.lookup = lookup;
		}

		@Override
		public Object invoke(Object proxy, Method method, Object[] args)
				throws Throwable {
			// TODO: Cache handles or pre-load them
			Object result;
			if (method.getDeclaringClass().isAssignableFrom(delegate.getClass())) {
				MethodHandle handle = lookup.unreflect(method);
				result = handle.bindTo(delegate).invokeWithArguments(args);
			}
			else if (!method.isDefault()) {
				throw new IllegalStateException(
					"Delegate must implement abstract methods from all mixins. Missed: " + method);
			}
			else {
				MethodHandle mh = getSuperMethodHandle(method, lookup);
				result = mh.bindTo(proxy).invokeWithArguments(args);
			}
			/**
			 * NOTE: I cannot replace the delegate with the proxy here (say, to prevent accidental
			 * leakage) for at least two reasons. 1) I may want direct access to the delegate. 2) It
			 * wouldn't work when the return value itself wraps or will provide the delegate (e.g.,
			 * a future).
			 */
			return result;
		}
	}
}

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Implement the named abstract method on the delegate class.
  2. Add a `default` implementation to the mixin interface if appropriate.
  3. Pass a delegate whose type already implements all the mixin interfaces.

Example fix

// before
class MyDelegate implements ReadMixin { /* missing op() from OpMixin */ }
Object p = ProxyUtilities.createProxy(new MyDelegate(), ReadMixin.class, OpMixin.class);
// after
class MyDelegate implements ReadMixin, OpMixin {
    @Override public void op() { /* ... */ }
}
Object p = ProxyUtilities.createProxy(new MyDelegate(), ReadMixin.class, OpMixin.class);
Defensive patterns

Strategy: validation

Validate before calling

for (Class<?> mixin : mixins) {
    for (Method m : mixin.getMethods()) {
        if (!Modifier.isDefault(m.getModifiers()) &&
            !Arrays.asList(delegate.getClass().getMethods()).toString().contains(m.getName())) {
            // check more precisely that delegate implements m's signature
        }
    }
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14). Data as JSON: /api/errors/dad74260bb7a64a8. Report an issue: GitHub.