code4craft/webmagic · error · IllegalArgumentException

wrong proto type map

Error message

wrong proto type map 

What it means

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.

Solutions

  1. Set protoMapClass to a concrete Map class with a public no-arg constructor, e.g. HashMap.class or LinkedHashMap.class.
  2. If using a custom Map implementation, add/restore a public no-arg constructor.
  3. Verify the constructor used to configure protoMapClass is passing the concrete class, not an interface or abstract base.

Example fix

// before
super(Map.class);
// after
super(HashMap.class);
Defensive patterns

Strategy: validation

Validate before calling

try {
    protoMapClass.getDeclaredConstructor().newInstance();
} catch (Exception e) {
    throw new IllegalStateException(protoMapClass + " needs a public no-arg constructor");
}

Type guard

static boolean isInstantiableMap(Class<?> c) {
    return Map.class.isAssignableFrom(c)
        && !c.isInterface()
        && !java.lang.reflect.Modifier.isAbstract(c.getModifiers());
}

Try / catch

try {
    mapOpsUsingProtoMap();
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("wrong proto type map")) {
        throw new IllegalStateException("Configure a concrete Map class like HashMap.class", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of code4craft/webmagic@67816a19d6 (2026-09-08). Data as JSON: /api/errors/5381678de6764970. Report an issue: GitHub.

Appendix: source

Thrown at webmagic-extension/src/main/java/us/codecraft/webmagic/utils/MultiKeyMapBase.java:34

    protected static final Class<? extends Map> DEFAULT_CLAZZ = HashMap.class;
    @SuppressWarnings("rawtypes")
    private Class<? extends Map> protoMapClass = DEFAULT_CLAZZ;

    public MultiKeyMapBase() {
    }

    @SuppressWarnings("rawtypes")
    public MultiKeyMapBase(Class<? extends Map> protoMapClass) {
        this.protoMapClass = protoMapClass;
    }

    @SuppressWarnings("unchecked")
    protected <K, V2> Map<K, V2> newMap() {
        try {
            return (Map<K, V2>) protoMapClass.newInstance();
        } catch (InstantiationException e) {
            throw new IllegalArgumentException("wrong proto type map "
                    + protoMapClass);
        } catch (IllegalAccessException e) {
            throw new IllegalArgumentException("wrong proto type map "
                    + protoMapClass);
        }
    }
}

View on GitHub (pinned to 67816a19d6)