{"record":{"id":"5381678de6764970","repo":"code4craft/webmagic","slug":"wrong-proto-type-map","errorCode":null,"errorMessage":"wrong proto type map ","messagePattern":"wrong proto type map ","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"webmagic-extension/src/main/java/us/codecraft/webmagic/utils/MultiKeyMapBase.java","lineNumber":34,"sourceCode":"\n    protected static final Class<? extends Map> DEFAULT_CLAZZ = HashMap.class;\n    @SuppressWarnings(\"rawtypes\")\n    private Class<? extends Map> protoMapClass = DEFAULT_CLAZZ;\n\n    public MultiKeyMapBase() {\n    }\n\n    @SuppressWarnings(\"rawtypes\")\n    public MultiKeyMapBase(Class<? extends Map> protoMapClass) {\n        this.protoMapClass = protoMapClass;\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    protected <K, V2> Map<K, V2> newMap() {\n        try {\n            return (Map<K, V2>) protoMapClass.newInstance();\n        } catch (InstantiationException e) {\n            throw new IllegalArgumentException(\"wrong proto type map \"\n                    + protoMapClass);\n        } catch (IllegalAccessException e) {\n            throw new IllegalArgumentException(\"wrong proto type map \"\n                    + protoMapClass);\n        }\n    }\n}","sourceCodeStart":16,"sourceCodeEnd":41,"githubUrl":"https://github.com/code4craft/webmagic/blob/67816a19d68a4fec4657bf1336227e046e251df2/webmagic-extension/src/main/java/us/codecraft/webmagic/utils/MultiKeyMapBase.java#L16-L41","documentation":"MultiKeyMapBase.newMap() instantiates the configured protoMapClass via reflection (Class.newInstance()). If the class is abstract, an interface, or has no accessible no-arg constructor, InstantiationException is thrown and rethrown as IllegalArgumentException \"wrong proto type map <class>\". This happens during map creation for every put/get in the multi-key map.","triggerScenarios":"Setting protoMapClass to an interface (e.g. Map.class), an abstract class (e.g. AbstractMap subclass without concrete impl), or any Map implementation lacking a public no-arg constructor, then calling newMap() via any map operation.","commonSituations":"Subclassing MultiKeyMapBase in a constructor chain and accidentally passing Map.class or an interface instead of HashMap.class/LinkedHashMap.class; refactoring away the default constructor of a custom map class.","solutions":["Set protoMapClass to a concrete Map class with a public no-arg constructor, e.g. HashMap.class or LinkedHashMap.class.","If using a custom Map implementation, add/restore a public no-arg constructor.","Verify the constructor used to configure protoMapClass is passing the concrete class, not an interface or abstract base."],"exampleFix":"// before\nsuper(Map.class);\n// after\nsuper(HashMap.class);","handlingStrategy":"validation","validationCode":"try {\n    protoMapClass.getDeclaredConstructor().newInstance();\n} catch (Exception e) {\n    throw new IllegalStateException(protoMapClass + \" needs a public no-arg constructor\");\n}","typeGuard":"static boolean isInstantiableMap(Class<?> c) {\n    return Map.class.isAssignableFrom(c)\n        && !c.isInterface()\n        && !java.lang.reflect.Modifier.isAbstract(c.getModifiers());\n}","tryCatchPattern":"try {\n    mapOpsUsingProtoMap();\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"wrong proto type map\")) {\n        throw new IllegalStateException(\"Configure a concrete Map class like HashMap.class\", e);\n    }\n    throw e;\n}","preventionTips":["Only pass concrete, public Map classes (HashMap, LinkedHashMap, TreeMap)","Add a unit test that instantiates the multi-key map at startup","Never configure interfaces or abstract classes as protoMapClass"],"tags":["java","reflection","configuration","map"],"backgroundTag":"invalid-config-value","analyzedSha":"67816a19d68a4fec4657bf1336227e046e251df2","analyzedAt":"2026-09-08T11:15:28.425Z","contentChangedAt":"2026-09-08T11:15:28.425Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}