oracle/graal · error · IOException
Should be recognized as signature:
Error message
Should be recognized as signature:
What it means
Thrown while serializing a ResolvedJavaMethod into the graph constant pool (POOL_METHOD entry). Before writing the signature, GraphProtocol calls findSignature(methodSignature) to locate or register the signature object in its pool; if that lookup returns null, the library cannot map the object returned by findMethodSignature to any poolable signature. In practice this means the GraphStructure/protocol customization returned an object that the signature pool does not recognize (e.g. a raw method, a null-ish wrapper, or an object whose class is not handled by findSignature). The stream is aborted with an IOException because continuing would emit an unparseable pool entry.
Solutions
- Make findMethodSignature return a real Signature-compatible object and ensure findSignature recognizes the exact same object/type (both methods must agree on the signature representation).
- If you replaced one of findMethodSignature/findSignature, override the matching counterpart so the pool lookup succeeds.
- When dumping mocks or synthetic methods, wrap their signatures in a concrete signature type the protocol already handles (e.g. a real jdk.vm.meta Signature implementation).
- Add a unit test that dumps a graph containing a method node to catch the mismatch before runtime.
Example fix
// before (custom GraphStructure)
@Override
public Object findMethodSignature(Object method) {
return method; // returns the method itself -> findSignature(method) == null -> IOException
}
// after
@Override
public Signature findMethodSignature(ResolvedJavaMethod method) {
return method.getSignature(); // a real Signature object the pool recognizes
} Defensive patterns
Strategy: validation
Validate before calling
// Before dumping, verify the signature round-trips through your own lookups
Signature sig = structure.findMethodSignature(method);
if (sig == null || protocol.findSignatureInPool(sig) == null) {
throw new IllegalStateException("Unrecognized method signature for " + method);
} Try / catch
try { protocol.dump(graph); } catch (IOException e) { if (e.getMessage().startsWith("Should be recognized as signature")) { /* fix findMethodSignature/findSignature pairing */ } throw e; } Prevention
- Override findMethodSignature and findSignature together so they agree on the signature representation.
- Unit-test dumping a graph that contains a method reference before shipping a custom GraphStructure.
- Never return the method object (or ad-hoc wrappers) from signature-returning methods.
When it happens
Trigger: Subclassing GraphProtocol/ProtocolImpl (or providing a custom GraphStructure) and overriding findMethodSignature so it returns something other than an object that findSignature can resolve; dumping a graph whose nodes reference a ResolvedJavaMethod whose signature object is of an unexpected type; partial overrides where findSignature was not overridden consistently with findMethodSignature.
Common situations: Custom graph dumpers built on the graphio library (e.g. dumping domain-specific graphs with method-like nodes), upgrades of GraalVM where the Signature abstraction changed, and test harnesses that feed mock ResolvedJavaMethod/Signature objects into the dumper.
Related errors
- classForNode method shall return node class representation…
- edgeType method shall return an enum! Was:
- nodeClassType method shall return a Java class (instance of…
- Property count is too big. Properties can contain only
- Bad pattern
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/e97a2ed0faa6be87.
Report an issue: GitHub.
Appendix: source
Thrown at compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graphio/GraphProtocol.java:761
if (enumValueNames != null) {
writeByte(ENUM_KLASS);
writeInt(enumValueNames.length);
for (String o : enumValueNames) {
writePoolObject(o);
}
} else {
writeByte(KLASS);
}
break;
}
case POOL_METHOD: {
ResolvedJavaMethod method = (ResolvedJavaMethod) found[0];
Objects.requireNonNull(method);
writePoolObject(findMethodDeclaringClass(method));
writePoolObject(findMethodName(method));
final Signature methodSignature = findMethodSignature(method);
if (findSignature(methodSignature) == null) {
throw new IOException("Should be recognized as signature: " + methodSignature + " for " + method);
}
writePoolObject(methodSignature);
writeInt(findMethodModifiers(method));
writeBytes(findMethodCode(method));
break;
}
case POOL_ENUM: {
int enumOrdinal = (int) found[0];
writePoolObject(findEnumClass(object));
writeInt(enumOrdinal);
break;
}
case POOL_STRING: {
writeString(object.toString());
break;
}
default:
throw new IllegalStateException();View on GitHub (pinned to a66e9ccd1d)