{"record":{"id":"eb2da017b82903ff","repo":"LSPosed/LSPosed","slug":"field-of-type-type-getname-in-class-clazz-g","errorCode":null,"errorMessage":"Field of type ${type.getName()} in class ${clazz.getName()}","messagePattern":"Field of type (.+?) in class (.+?)","errorType":"exception","errorClass":"NoSuchFieldError","httpStatus":null,"severity":"error","filePath":"core/src/main/java/de/robv/android/xposed/XposedHelpers.java","lineNumber":303,"sourceCode":"     * Might be useful for Proguard'ed classes to identify fields with unique types.\n     *\n     * @param clazz The class which either declares or inherits the field.\n     * @param type  The type of the field.\n     * @return A reference to the first field of the given type.\n     * @throws NoSuchFieldError In case no matching field was not found.\n     */\n    public static Field findFirstFieldByExactType(Class<?> clazz, Class<?> type) {\n        Class<?> clz = clazz;\n        do {\n            for (Field field : clz.getDeclaredFields()) {\n                if (field.getType() == type) {\n                    field.setAccessible(true);\n                    return field;\n                }\n            }\n        } while ((clz = clz.getSuperclass()) != null);\n\n        throw new NoSuchFieldError(\"Field of type \" + type.getName() + \" in class \" + clazz.getName());\n    }\n\n    /**\n     * Look up a method and hook it. See {@link #findAndHookMethod(String, ClassLoader, String, Object...)}\n     * for details.\n     */\n    public static XC_MethodHook.Unhook findAndHookMethod(Class<?> clazz, String methodName, Object... parameterTypesAndCallback) {\n        if (parameterTypesAndCallback.length == 0 || !(parameterTypesAndCallback[parameterTypesAndCallback.length - 1] instanceof XC_MethodHook))\n            throw new IllegalArgumentException(\"no callback defined\");\n\n        XC_MethodHook callback = (XC_MethodHook) parameterTypesAndCallback[parameterTypesAndCallback.length - 1];\n        Method m = findMethodExact(clazz, methodName, getParameterClasses(clazz.getClassLoader(), parameterTypesAndCallback));\n\n        return XposedBridge.hookMethod(m, callback);\n    }\n\n    /**\n     * Look up a method and hook it. The last argument must be the callback for the hook.","sourceCodeStart":285,"sourceCodeEnd":321,"githubUrl":"https://github.com/LSPosed/LSPosed/blob/df74d83eb03a44cc6ad268841ac2ada28d077c77/core/src/main/java/de/robv/android/xposed/XposedHelpers.java#L285-L321","documentation":"XposedHelpers.findFirstFieldByExactType(Class, Class) walks the class hierarchy (getDeclaredFields on each level up to Object) looking for the first field whose declared type exactly matches (== identity, not assignability) the given type. If none matches it throws NoSuchFieldError with the type and class names. Note it is an Error, not an exception — a bug carried over from the original Xposed API for fail-fast module development.","triggerScenarios":"findFirstFieldByExactType(clazz, SomeType.class) where no field in clazz or any superclass is declared exactly as SomeType (a subclass field, a generic Object field, or an inherited field with a different declared type all fail).","commonSituations":"Android OEM updates change a framework field's declared type (e.g. a field refactored from a concrete type to an interface or vice versa); the field exists on a sibling class instead of a superclass; passing a subtype of the actual declared type (assignability is not considered); obfuscation/renaming in target apps.","solutions":["Verify the field exists with the exact declared type: dump clazz.getDeclaredFields() across the hierarchy and check field.getType() == wantedType.","If the declared type changed, search by that exact type, or switch to XposedHelpers.findField(clazz, name) if the name is stable.","Wrap the call in try/catch (NoSuchFieldError | Throwable) to degrade gracefully per Android version / OEM.","For subtype tolerance write a small loop using isAssignableFrom instead of this exact-match helper."],"exampleFix":"// before\nField f = XposedHelpers.findFirstFieldByExactType(Activity.class, WindowManager.class); // NoSuchFieldError\n\n// after\nField f = null;\ntry {\n    f = XposedHelpers.findFirstFieldByExactType(Activity.class, WindowManager.class);\n} catch (NoSuchFieldError e) {\n    // version-specific layout: fall back to named lookup or skip feature\n    f = XposedHelpers.findField(Activity.class, \"mWindowManager\");\n}","handlingStrategy":"try-catch","validationCode":"static Field findFirstFieldByExactTypeSafe(Class<?> clazz, Class<?> type) {\n    for (Class<?> c = clazz; c != null; c = c.getSuperclass())\n        for (Field f : c.getDeclaredFields())\n            if (f.getType() == type) return f;\n    return null;\n}","typeGuard":null,"tryCatchPattern":"try {\n    f = XposedHelpers.findFirstFieldByExactType(clazz, type);\n} catch (NoSuchFieldError e) { // API throws Error, not Exception\n    // version/OEM mismatch: skip feature or use named lookup\n}","preventionTips":["Remember the helper matches types by identity (==), not assignability.","Wrap framework field lookups per Android version; signatures drift across OEM builds.","Dump the target class hierarchy's declared fields once during development to confirm exact types."],"tags":["xposed","android","reflection","field-lookup","version-fragility"],"backgroundTag":null,"analyzedSha":"df74d83eb03a44cc6ad268841ac2ada28d077c77","analyzedAt":"2026-08-14T10:46:48.326Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}