java-decompiler/jd-gui · error · RuntimeException
SignatureWriter.WriteSignature: invalid signature '${descrip
Error message
SignatureWriter.WriteSignature: invalid signature '${descriptor}' What it means
The signature writer in AbstractTypeFactoryProvider converts JVM type descriptors (e.g. 'Ljava/lang/String;') into readable Java types. When it encounters a character at the start of a type that is not a recognized descriptor or wildcard/signature marker (invalid 'BaseType' character), it throws a RuntimeException naming the whole descriptor. This guards against corrupted class files or descriptors that were truncated or parsed at a wrong index.
Source
Thrown at services/src/main/java/org/jd/gui/service/type/AbstractTypeFactoryProvider.java:168
beginIndex = ++index;
index = descriptor.substring(beginIndex, length).indexOf(';');
sb.append(descriptor.substring(beginIndex, index));
index++;
break;
case 'V': sb.append("void"); index++; break;
case 'Z': sb.append("boolean"); index++; break;
case '-':
sb.append("? super ");
index = writeSignature(sb, descriptor, length, index+1, false);
break;
case '+':
sb.append("? extends ");
index = writeSignature(sb, descriptor, length, index+1, false);
break;
case '*': sb.append('?'); index++; break;
case 'X': case 'Y': sb.append("int"); index++; break;
default:
throw new RuntimeException("SignatureWriter.WriteSignature: invalid signature '" + descriptor + "'");
}
if (varargsFlag) {
if (dimensionLength > 0) {
while (--dimensionLength > 0)
sb.append("[]");
sb.append("...");
}
} else {
while (dimensionLength-- > 0)
sb.append("[]");
}
if ((index >= length) || (descriptor.charAt(index) != '.'))
break;
sb.append('.');
}View on GitHub (pinned to b3c1ced04e)
Solutions
- Verify the class file is valid: recompile or re-obtain the artifact from a trusted source (javap -v can confirm the Signature/descriptor attributes).
- Check that the descriptor string passed to the type factory is a full type descriptor and not truncated or offset — a wrong starting index lands mid-identifier and hits the default branch.
- Upgrade JD-GUI to the latest release; support for signature encodings has been extended over time.
- If you maintain the code, log the failing index and character before throwing to pinpoint which construct is unsupported.
Example fix
// before
default:
throw new RuntimeException("SignatureWriter.WriteSignature: invalid signature '" + descriptor + "'");
// after
default:
if (Character.isJavaIdentifierStart(c)) { // fallback: treat as class name char
sb.append(c); index++; break;
}
throw new RuntimeException("SignatureWriter.WriteSignature: invalid signature '" + descriptor + "' at index " + index + " char '" + c + "'"); Defensive patterns
Strategy: validation
Validate before calling
// Check the descriptor starts with a legal BaseType/ObjectType/ArrayType char
boolean isLikelyValidTypeDescriptor(String d) {
if (d == null || d.isEmpty()) return false;
char c = d.charAt(0);
return "BCDFIJSVZ".indexOf(c) >= 0 || c == 'L' || c == '[' || c == 'T' || c == '+' || c == '-' || c == '*';
} Type guard
boolean isObjectTypeDescriptor(String d) {
return d != null && d.startsWith("L") && d.endsWith(";");
} Try / catch
try {
String readable = typeFactory.make(api, entry, descriptor).getDisplayTypeName();
} catch (RuntimeException ex) {
if (ex.getMessage() != null && ex.getMessage().startsWith("SignatureWriter.WriteSignature:")) {
// fall back to showing the raw descriptor
readable = descriptor;
} else throw ex;
} Prevention
- Only pass complete type descriptors (never truncated or index-offset strings) into signature rendering
- Validate class files before decompiling (javap -v or a class-file verifier)
- Keep JD-GUI updated for newer signature encodings
- Log descriptor plus current index/char before throwing to aid diagnosis
When it happens
Trigger: writeSignature (or writeMethodSignature via it) processing a descriptor whose current character is not one of B/C/D/F/I/J/S/V/Z/L/T/[/*+/-/X/Y — typically a truncated descriptor, an index pointing mid-identifier, or a class file with corrupted constant-pool/Signature attributes.
Common situations: Opening a class file compiled by a non-standard or buggy compiler; obfuscated or deliberately malformed bytecode; a JD-GUI version not supporting newer signature constructs (e.g. some compilations with X/Y handling); passing a method descriptor instead of a field/type descriptor into the type factory.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
AI-assisted analysis of java-decompiler/jd-gui@b3c1ced04e (2026-09-06).
Data as JSON: /api/errors/bf341d0d7e5b9f6f.
Report an issue: GitHub.