oracle/graal · error · ElementException
Node class constructor must be public or protected
Error message
Node class constructor must be public or protected
What it means
Every declared constructor of a @NodeInfo node class must be public or protected (private ones are simply skipped as internal helpers, e.g. for vannatable constructors). Package-private constructors would prevent the generated node metas and instantiation machinery from creating the node reliably across packages. GraphNodeVerifier throws this ElementException on the offending constructor during annotation processing.
Solutions
- Add protected or public to the constructor declaration.
- If the constructor is internal-only, make it private so the verifier skips it — but then ensure at least one non-private constructor remains (else error 'Node class must have at least one protected constructor' follows).
- Rebuild to confirm.
Example fix
// before
MyNode(ValueNode x) {
super(...);
}
// after
protected MyNode(ValueNode x) {
super(...);
} Defensive patterns
Strategy: validation
Prevention
- Always write an explicit access modifier on node constructors (Java's default package-private is rejected).
- Keep node constructors protected unless the node is meant to be instantiated broadly.
When it happens
Trigger: A constructor whose modifiers contain neither PRIVATE, PUBLIC nor PROTECTED — i.e. package-private — is found by ElementFilter.constructorsIn(node.getEnclosedElements()) (GraphNodeVerifier.java:211-216). Example: 'MyNode(ValueNode x) { ... }' with no visibility modifier.
Common situations: Adding a helper constructor without an access modifier (Java defaults to package-private); refactoring visibility during test wiring; nodes in packages different from where they are instantiated.
Related errors
- Node class must have at least one protected constructor
- Data field must be final if public
- Input field must not be final
- Input field must not be public
- Input field type must be an interface or assignable to Node
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/d9be299c4fc938a5.
Report an issue: GitHub.
Appendix: source
Thrown at compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/nodeinfo/processor/GraphNodeVerifier.java:215
return processor.env().getTypeUtils().isSameType(type1, type2);
}
private TypeElement getSuperType(TypeElement element) {
if (element.getSuperclass() != null) {
return processor.asTypeElement(element.getSuperclass());
}
return null;
}
void verify(TypeElement node) {
scanFields(node);
boolean foundValidConstructor = false;
for (ExecutableElement constructor : ElementFilter.constructorsIn(node.getEnclosedElements())) {
if (constructor.getModifiers().contains(PRIVATE)) {
continue;
} else if (!constructor.getModifiers().contains(PUBLIC) && !constructor.getModifiers().contains(PROTECTED)) {
throw new ElementException(constructor, "Node class constructor must be public or protected");
}
foundValidConstructor = true;
}
if (!foundValidConstructor) {
throw new ElementException(node, "Node class must have at least one protected constructor");
}
}
}
View on GitHub (pinned to a66e9ccd1d)