NationalSecurityAgency/ghidra · error · IllegalArgumentException
Constructor must be a non-static method
Error message
Constructor must be a non-static method
What it means
Thrown by DependentServiceResolver.addClass() when a method annotated @DependentService is declared static. The DI framework constructs services by invoking the factory on a receiver instance, so a static method has no valid receiver and cannot participate. Non-static is an enforced precondition.
Source
Thrown at Ghidra/Debug/ProposedUtils/src/main/java/generic/depends/DependentServiceResolver.java:75
}
Class<?> superCls = cls.getSuperclass();
if (superCls == null) {
return;
}
addClass(superCls);
for (Class<?> superIf : cls.getInterfaces()) {
addClass(superIf);
}
for (Method m : cls.getDeclaredMethods()) {
DependentService annot = m.getAnnotation(DependentService.class);
if (annot == null) {
continue;
}
int mods = m.getModifiers();
if (Modifier.isStatic(mods)) {
throw new IllegalArgumentException("Constructor must be a non-static method");
}
Class<?> override = annot.override();
Class<?> rCls = m.getReturnType();
if (override != DependentService.Sentinel.class) {
if (!override.isAssignableFrom(rCls)) {
throw new IllegalArgumentException(
"Overridden constructor must return same or subclass of original");
}
depsByDependents.computeIfAbsent(override, o -> new HashSet<>()).add(rCls);
constructors.put(override, m);
}
constructors.put(rCls, m);
m.setAccessible(true);
for (Class<?> pType : m.getParameterTypes()) {
depsByDependents.computeIfAbsent(rCls, c -> new HashSet<>()).add(pType);
}View on GitHub (pinned to d5f144c24d)
Solutions
- Make the @DependentService method an instance (non-static) method.
- If the logic must be static, wrap it in a thin instance method that delegates to the static helper, and annotate only the instance method.
- Remove @DependentService from methods that should not be DI factories.
Example fix
// before
public class Factory {
@DependentService
public static MyService create() { return new MyService(); } // static -> throws
}
// after
public class Factory {
@DependentService
public MyService create() { return new MyService(); } // instance method
} Defensive patterns
Strategy: validation
Validate before calling
for (Method m : cls.getDeclaredMethods()) {
if (m.getAnnotation(DependentService.class) != null &&
Modifier.isStatic(m.getModifiers())) {
throw new IllegalStateException("Remove @DependentService or de-static " + m);
}
} Prevention
- Keep @DependentService methods instance-level.
- Run a build/test after converting any method to static.
- Use static analysis or a reflective test to scan for static annotated methods.
When it happens
Trigger: Adding @DependentService to a static helper or utility method. Declaring the factory method static because it does not use instance state. Migrating an instance method to static and forgetting to drop the annotation.
Common situations: Refactoring that turns an instance factory method static; utility-class-style service factories; copy-paste of an annotation onto a static builder method.
Related errors
- Constructor method must return type assignable to the class
- Error constructing dependent service via {}
- Overridden constructor must return same or subclass of origi
- There are fields without suitable constructors: {}
- Could not resolve required parameter for next in: {}. Note:
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/5063bb4145d665f3.
Report an issue: GitHub.