apache/hadoop · error · IllegalArgumentException
Not a primitive: {declaredClass}
Error message
Not a primitive: {declaredClass} What it means
Thrown by ObjectWritable.writeObject when declaredClass.isPrimitive() is true but the class matches none of the handled TYPE constants (Boolean, Byte, Character, Short, Integer, Long, Float, Double, Void). It is the terminal else of the primitive-dispatch chain: the declared class claimed to be a primitive yet was not one this serializer knows how to emit, which on a standard JVM indicates corrupted state or an exotic class object rather than a normal data problem.
Source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/ObjectWritable.java:220
if (declaredClass == Boolean.TYPE) { // boolean
out.writeBoolean(((Boolean)instance).booleanValue());
} else if (declaredClass == Character.TYPE) { // char
out.writeChar(((Character)instance).charValue());
} else if (declaredClass == Byte.TYPE) { // byte
out.writeByte(((Byte)instance).byteValue());
} else if (declaredClass == Short.TYPE) { // short
out.writeShort(((Short)instance).shortValue());
} else if (declaredClass == Integer.TYPE) { // int
out.writeInt(((Integer)instance).intValue());
} else if (declaredClass == Long.TYPE) { // long
out.writeLong(((Long)instance).longValue());
} else if (declaredClass == Float.TYPE) { // float
out.writeFloat(((Float)instance).floatValue());
} else if (declaredClass == Double.TYPE) { // double
out.writeDouble(((Double)instance).doubleValue());
} else if (declaredClass == Void.TYPE) { // void
} else {
throw new IllegalArgumentException("Not a primitive: "+declaredClass);
}
} else if (declaredClass.isEnum()) { // enum
UTF8.writeString(out, ((Enum)instance).name());
} else if (Writable.class.isAssignableFrom(declaredClass)) { // Writable
UTF8.writeString(out, instance.getClass().getName());
((Writable)instance).write(out);
} else if (Message.class.isAssignableFrom(declaredClass)) {
((Message)instance).writeDelimitedTo(
DataOutputOutputStream.constructOutputStream(out));
} else {
throw new IOException("Can't write: "+instance+" as "+declaredClass);
}
}
/**
* Read a {@link Writable}, {@link String}, primitive type, or an array ofView on GitHub (pinned to 2add963021)
Solutions
- Log declaredClass.getName() at the throw site to identify which bogus Class value is flowing in.
- Fix how declaredClass is derived — it must be one of the eight primitive TYPE constants or one of the supported reference types (String, enum, Writable, protobuf Message, arrays).
- If the value is a wrapper object and you don't need primitive encoding, pass the wrapper class (Integer.class) instead of Integer.TYPE.
Example fix
// before: wrong field type object routed into ObjectWritable
Object o = 7;
Class<?> c = int.class; // handled, but suppose c came from a buggy lookup returning a fake primitive
ObjectWritable.writeObject(out, o, c, conf);
// after: validate the declared class against supported primitives up front
if (c.isPrimitive() && !SUPPORTED_PRIMITIVES.contains(c)) {
throw new IllegalArgumentException("Unsupported declared class: " + c);
}
ObjectWritable.writeObject(out, o, c, conf); Defensive patterns
Strategy: type-guard
Validate before calling
private static final Set<Class<?>> SUPPORTED = new HashSet<>(Arrays.asList(
Boolean.TYPE, Byte.TYPE, Character.TYPE, Short.TYPE, Integer.TYPE,
Long.TYPE, Float.TYPE, Double.TYPE, Void.TYPE));
if (declaredClass.isPrimitive() && !SUPPORTED.contains(declaredClass)) {
throw new IllegalArgumentException("Unsupported declared class " + declaredClass);
} Type guard
static boolean isObjectWritablePrimitive(Class<?> c) {
return c == Boolean.TYPE || c == Byte.TYPE || c == Character.TYPE
|| c == Short.TYPE || c == Integer.TYPE || c == Long.TYPE
|| c == Float.TYPE || c == Double.TYPE || c == Void.TYPE;
} Prevention
- Keep the declaredClass derivation (field.getType(), method parameter types) versioned and unit-tested against real serialization round-trips.
- Round-trip test every type you serialize through ObjectWritable: writeObject then readObject and assert equality.
- Prefer reference types (String, Writable, enum) over reflective primitives in new schemas — they fail louder and earlier.
When it happens
Trigger: Calling writeObject(out, instance, declaredClass, conf) with a Class object whose isPrimitive() lies or with a pseudo-primitive from a non-standard JVM/language runtime; more practically, reaching this branch through a bug where declaredClass was computed wrongly (e.g. getClass() vs field type mix-ups in RPC parameter serialization).
Common situations: Hand-rolled RPC/serialization code using ObjectWritable for generic fields; cross-language or bytecode-manipulation runtimes that produce nonstandard primitive Class objects; regressions after refactoring reflection code that derives declaredClass.
Related errors
- Can't write: {instance} as {declaredClass}
- Errors on getting mount table loader class. The fs.viewfs.mo
- Cannot initialize the class: {clazz}
- Invalid size: {size}
- readObject can't find class {className}
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/abfcf78252d603a7.
Report an issue: GitHub.