skylot/jadx · error · JadxRuntimeException

Not class type: {}

Error message

Not class type: {}

What it means

Thrown by ClassInfo.checkClassType when the ArgType is non-null but is neither an object type nor is a generic type (type.isObject() false, or type.isGenericType() true). It enforces that a ClassInfo only describes a concrete class type, not a primitive, a bare type variable, or an unparameterised generic.

Source

Thrown at jadx-core/src/main/java/jadx/core/dex/info/ClassInfo.java:59

	public static ClassInfo fromName(RootNode root, String clsName) {
		return fromType(root, ArgType.object(clsName));
	}

	public static ClassInfo fromNameWithoutCache(RootNode root, String fullClsName, boolean canBeInner) {
		return new ClassInfo(root, ArgType.object(fullClsName), canBeInner);
	}

	private static ArgType checkClassType(ArgType type) {
		if (type == null) {
			throw new JadxRuntimeException("Null class type");
		}
		if (type.isArray()) {
			// TODO: check case with method declared in array class like ( clone in int[])
			return ArgType.OBJECT;
		}
		if (!type.isObject() || type.isGenericType()) {
			throw new JadxRuntimeException("Not class type: " + type);
		}
		if (type.isGeneric()) {
			return ArgType.object(type.getObject());
		}
		return type;
	}

	public void changeShortName(String aliasName) {
		ClassAliasInfo newAlias;
		String aliasPkg = getAliasPkg();
		if (Objects.equals(name, aliasName) || StringUtils.isEmpty(aliasName)) {
			if (Objects.equals(getPackage(), aliasPkg)) {
				newAlias = null;
			} else {
				newAlias = new ClassAliasInfo(aliasPkg, name);
			}
		} else {
			newAlias = new ClassAliasInfo(aliasPkg, aliasName);

View on GitHub (pinned to e738a26571)

Solutions

  1. Before building ClassInfo, check type.isObject() && !type.isGenericType(); if not, handle via the appropriate (generic/primitive) path instead.
  2. For generic types, extract the raw object type first: ArgType.object(type.getObject()).
  3. Inspect the offending ArgType (printed in the message) to see why it is not a class type.
  4. Fix the upstream descriptor/type parsing that produced the wrong kind.

Example fix

// before
ClassInfo info = ClassInfo.fromType(root, type); // throws for primitives/generics

// after
if (type == null) {
    return null;
}
if (!type.isObject() || type.isGenericType()) {
    if (type.isGeneric()) {
        type = ArgType.object(type.getObject()); // use raw type
    } else {
        throw new IllegalArgumentException("Not a class type: " + type);
    }
}
ClassInfo info = ClassInfo.fromType(root, type);
Defensive patterns

Strategy: type-guard

Validate before calling

if (type == null || !type.isObject() || type.isGenericType()) {
    if (type != null && type.isGeneric()) {
        type = ArgType.object(type.getObject()); // use raw type
    } else {
        throw new IllegalArgumentException("Not a class type: " + type);
    }
}

Type guard

static boolean isClassType(ArgType t) {
    return t != null && t.isObject() && !t.isGenericType();
}

Try / catch

try {
    return ClassInfo.fromType(root, type);
} catch (JadxRuntimeException e) {
    if (type != null && type.isGeneric()) {
        return ClassInfo.fromType(root, ArgType.object(type.getObject()));
    }
    throw e;
}

Prevention

When it happens

Trigger: Passing an ArgType that is a primitive (INT, etc.), a type variable (e.g. T), or a generic-type-token where a concrete class is required. Happens when class resolution is fed a type that does not denote an actual class.

Common situations: Misrouting generic/type-variable resolution into class-info lookup; parsing a type descriptor incorrectly so it is not recognised as OBJECT; obfuscated descriptors that resolve to a generic instead of a class.

Related errors


AI-assisted analysis of skylot/jadx@e738a26571 (2026-08-14). Data as JSON: /api/errors/fe679f99116641e1. Report an issue: GitHub.