{"record":{"id":"9c707732c7929a3f","repo":"apache/dubbo","slug":"illegal-constructor-cls-getname","errorCode":null,"errorMessage":"Illegal constructor: ${cls.getName()}","messagePattern":"Illegal constructor: (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"dubbo-common/src/main/java/org/apache/dubbo/common/utils/PojoUtils.java","lineNumber":694,"sourceCode":"        } catch (Exception t) {\n            return newInstance(cls);\n        }\n    }\n\n    private static Object newInstance(Class<?> cls) {\n        try {\n            return cls.getDeclaredConstructor().newInstance();\n        } catch (Exception t) {\n            Constructor<?>[] constructors = cls.getDeclaredConstructors();\n            /*\n             From Javadoc java.lang.Class#getDeclaredConstructors\n             This method returns an array of Constructor objects reflecting all the constructors\n             declared by the class represented by this Class object.\n             This method returns an array of length 0,\n             if this Class object represents an interface, a primitive type, an array class, or void.\n            */\n            if (constructors.length == 0) {\n                throw new RuntimeException(\"Illegal constructor: \" + cls.getName());\n            }\n            Throwable lastError = null;\n            Arrays.sort(constructors, Comparator.comparingInt(a -> a.getParameterTypes().length));\n            for (Constructor<?> constructor : constructors) {\n                try {\n                    constructor.setAccessible(true);\n                    Object[] parameters = Arrays.stream(constructor.getParameterTypes())\n                            .map(PojoUtils::getDefaultValue)\n                            .toArray();\n                    return constructor.newInstance(parameters);\n                } catch (Exception e) {\n                    lastError = e;\n                }\n            }\n            throw new RuntimeException(lastError.getMessage(), lastError);\n        }\n    }\n","sourceCodeStart":676,"sourceCodeEnd":712,"githubUrl":"https://github.com/apache/dubbo/blob/3a3043227f5571d25eb2889de5bca22f2914843b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/PojoUtils.java#L676-L712","documentation":"When PojoUtils needs to instantiate a class during realization, it first tries the no-arg constructor. If that fails, it checks getDeclaredConstructors(). Per the Java spec, that method returns an empty array for interfaces, primitive types, array classes, and void. An empty array means there is no way to instantiate, so a RuntimeException is thrown naming the class.","triggerScenarios":"Calling PojoUtils.newInstance(cls) (indirectly via realize) where cls is an interface, a primitive type (int.class), an array class, or void.class. These types have no constructors and cannot be instantiated via reflection.","commonSituations":"A generic RPC where the target type metadata resolves to an interface instead of a concrete class, or a deserialization target is incorrectly specified as a primitive or array type. The realize0 logic should normally handle interfaces by finding an implementation, but if the code path reaches newInstance with an interface, it fails here.","solutions":["Ensure the target type for realization is a concrete instantiable class with at least one constructor, not an interface or primitive.","If the type is an interface, provide the concrete implementation class name in the generic map ('class' key) or configure the provider to return a concrete type.","Check that the method return type or parameter type metadata on the provider side points to a concrete class.","Verify the GENERIC_WITH_CLZ setting and that the serialized form includes the concrete class name."],"exampleFix":"// before — interface as target type\nPojoUtils.realize(map, MyInterface.class);\n// after — concrete class\nPojoUtils.realize(map, MyInterfaceImpl.class);\n// or include class name in the map\nmap.put(\"class\", \"com.example.MyInterfaceImpl\");\nPojoUtils.realize(map, MyInterface.class);","handlingStrategy":"validation","validationCode":"// Validate the class is instantiable before passing to realize\nif (type.isInterface() || type.isPrimitive() || type.isArray() || type == Void.class) {\n    throw new IllegalArgumentException(\n        \"Cannot realize into non-instantiable type: \" + type.getName()\n        + \". Provide a concrete class.\");\n}\nPojoUtils.realize(map, type);","typeGuard":"// Type guard for instantiable types\nstatic boolean isInstantiable(Class<?> cls) {\n    return !cls.isInterface() && !cls.isPrimitive()\n        && !cls.isArray() && cls != Void.class;\n}","tryCatchPattern":null,"preventionTips":["Always target realization at concrete classes, not interfaces or primitives.","Include the concrete class name in the generic Map ('class' key) so PojoUtils can resolve the implementation.","Configure provider return/parameter types as concrete classes in the service interface."],"tags":["pojo","reflection","instantiation","interface","deserialization"],"backgroundTag":null,"analyzedSha":"3a3043227f5571d25eb2889de5bca22f2914843b","analyzedAt":"2026-08-14T00:43:19.853Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}