{"record":{"id":"54abe259dd852583","repo":"mybatis/mybatis-3","slug":"the-2nd-arg-must-be-class-or-parameterizedtype-bu","errorCode":null,"errorMessage":"The 2nd arg must be Class or ParameterizedType, but was: {}","messagePattern":"The 2nd arg must be Class or ParameterizedType, but was: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/apache/ibatis/reflection/TypeParameterResolver.java","lineNumber":161,"sourceCode":"\n  private static Type resolveTypeVar(TypeVariable<?> typeVar, Type srcType, Class<?> declaringClass) {\n    Type result;\n    Class<?> clazz;\n    if (srcType instanceof Class) {\n      clazz = (Class<?>) srcType;\n    } else if (srcType instanceof ParameterizedType) {\n      ParameterizedType parameterizedType = (ParameterizedType) srcType;\n      clazz = (Class<?>) parameterizedType.getRawType();\n      if (clazz == declaringClass) {\n        TypeVariable<?>[] typeVars = declaringClass.getTypeParameters();\n        for (int i = 0; i < typeVars.length; i++) {\n          if (typeVar.equals(typeVars[i])) {\n            return parameterizedType.getActualTypeArguments()[i];\n          }\n        }\n      }\n    } else {\n      throw new IllegalArgumentException(\n          \"The 2nd arg must be Class or ParameterizedType, but was: \" + srcType.getClass());\n    }\n\n    if (clazz == declaringClass) {\n      Type[] bounds = typeVar.getBounds();\n      if (bounds.length > 0) {\n        return bounds[0];\n      }\n      return Object.class;\n    }\n\n    Type superclass = clazz.getGenericSuperclass();\n    result = scanSuperTypes(typeVar, srcType, declaringClass, clazz, superclass);\n    if (result != null) {\n      return result;\n    }\n\n    Type[] superInterfaces = clazz.getGenericInterfaces();","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/mybatis/mybatis-3/blob/008069adb1b089579b5dcba87ee591908b263274/src/main/java/org/apache/ibatis/reflection/TypeParameterResolver.java#L143-L179","documentation":"TypeParameterResolver.resolveTypeVar requires the source type (the class the member was declared against) to be a plain Class or a ParameterizedType. Any other Type implementation — a TypeVariable, WildcardType, or GenericArrayType — is rejected with IllegalArgumentException.","triggerScenarios":"Resolving a member whose declaring 'class' is itself unresolved: e.g. subclass hierarchies where getGenericSuperclass() returns a TypeVariable or a generic array because the concrete type arguments were never supplied (raw subclass of a generic base).","commonSituations":"Raw types: class MyMapper extends BaseMapper without <T> argument; wildcard/generic-array boundaries in deeply generic mappers or type handlers; custom reflection tooling calling TypeParameterResolver directly with unresolved Types.","solutions":["Supply concrete type arguments: class MyMapper extends BaseMapper<User> instead of raw BaseMapper.","If you call TypeParameterResolver directly, materialize ParameterizedTypes (e.g. via TypeToken/ParameterizedTypeImpl) before passing srcType.","Simplify the generic signature at the failing boundary so the declaring type is a Class or fully parameterized type."],"exampleFix":"// before\nclass UserDao extends BaseDao { ... }  // raw, T unresolved\n// after\nclass UserDao extends BaseDao<User> { ... }","handlingStrategy":"type-guard","validationCode":"if (!(srcType instanceof Class) && !(srcType instanceof ParameterizedType)) {\n  throw new IllegalArgumentException(\"resolve srcType to Class/ParameterizedType first\");\n}","typeGuard":"boolean resolvableType(Type t) {\n  return t instanceof Class || t instanceof ParameterizedType;\n}","tryCatchPattern":null,"preventionTips":["Never subclass generic MyBatis base types raw; always pass concrete type arguments.","When doing custom reflection, materialize ParameterizedType instances before delegating to TypeParameterResolver."],"tags":["mybatis","reflection","generics","type-erasure"],"backgroundTag":null,"analyzedSha":"008069adb1b089579b5dcba87ee591908b263274","analyzedAt":"2026-08-14T13:07:10.264Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}