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.

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)

Solutions

  1. 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).
  2. If you replaced one of findMethodSignature/findSignature, override the matching counterpart so the pool lookup succeeds.
  3. 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).
  4. 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

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


AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14). Data as JSON: /api/errors/e97a2ed0faa6be87. Report an issue: GitHub.