{"record":{"id":"abfcf78252d603a7","repo":"apache/hadoop","slug":"not-a-primitive-declaredclass","errorCode":null,"errorMessage":"Not a primitive: {declaredClass}","messagePattern":"Not a primitive: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/ObjectWritable.java","lineNumber":220,"sourceCode":"      if (declaredClass == Boolean.TYPE) {        // boolean\n        out.writeBoolean(((Boolean)instance).booleanValue());\n      } else if (declaredClass == Character.TYPE) { // char\n        out.writeChar(((Character)instance).charValue());\n      } else if (declaredClass == Byte.TYPE) {    // byte\n        out.writeByte(((Byte)instance).byteValue());\n      } else if (declaredClass == Short.TYPE) {   // short\n        out.writeShort(((Short)instance).shortValue());\n      } else if (declaredClass == Integer.TYPE) { // int\n        out.writeInt(((Integer)instance).intValue());\n      } else if (declaredClass == Long.TYPE) {    // long\n        out.writeLong(((Long)instance).longValue());\n      } else if (declaredClass == Float.TYPE) {   // float\n        out.writeFloat(((Float)instance).floatValue());\n      } else if (declaredClass == Double.TYPE) {  // double\n        out.writeDouble(((Double)instance).doubleValue());\n      } else if (declaredClass == Void.TYPE) {    // void\n      } else {\n        throw new IllegalArgumentException(\"Not a primitive: \"+declaredClass);\n      }\n    } else if (declaredClass.isEnum()) {         // enum\n      UTF8.writeString(out, ((Enum)instance).name());\n    } else if (Writable.class.isAssignableFrom(declaredClass)) { // Writable\n      UTF8.writeString(out, instance.getClass().getName());\n      ((Writable)instance).write(out);\n\n    } else if (Message.class.isAssignableFrom(declaredClass)) {\n      ((Message)instance).writeDelimitedTo(\n          DataOutputOutputStream.constructOutputStream(out));\n    } else {\n      throw new IOException(\"Can't write: \"+instance+\" as \"+declaredClass);\n    }\n  }\n  \n  \n  /**\n   * Read a {@link Writable}, {@link String}, primitive type, or an array of","sourceCodeStart":202,"sourceCodeEnd":238,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/ObjectWritable.java#L202-L238","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before: wrong field type object routed into ObjectWritable\nObject o = 7;\nClass<?> c = int.class; // handled, but suppose c came from a buggy lookup returning a fake primitive\nObjectWritable.writeObject(out, o, c, conf);\n\n// after: validate the declared class against supported primitives up front\nif (c.isPrimitive() && !SUPPORTED_PRIMITIVES.contains(c)) {\n  throw new IllegalArgumentException(\"Unsupported declared class: \" + c);\n}\nObjectWritable.writeObject(out, o, c, conf);","handlingStrategy":"type-guard","validationCode":"private static final Set<Class<?>> SUPPORTED = new HashSet<>(Arrays.asList(\n    Boolean.TYPE, Byte.TYPE, Character.TYPE, Short.TYPE, Integer.TYPE,\n    Long.TYPE, Float.TYPE, Double.TYPE, Void.TYPE));\nif (declaredClass.isPrimitive() && !SUPPORTED.contains(declaredClass)) {\n  throw new IllegalArgumentException(\"Unsupported declared class \" + declaredClass);\n}","typeGuard":"static boolean isObjectWritablePrimitive(Class<?> c) {\n  return c == Boolean.TYPE || c == Byte.TYPE || c == Character.TYPE\n      || c == Short.TYPE || c == Integer.TYPE || c == Long.TYPE\n      || c == Float.TYPE || c == Double.TYPE || c == Void.TYPE;\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["serialization","object-writable","reflection","hadoop-common"],"backgroundTag":"unsupported-type-serialization","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}