{"record":{"id":"c30f88f5a5d6da7b","repo":"Justson/AgentWeb","slug":"this-object-has-not-offer-method-javascript-to-cal-c30f88","errorCode":null,"errorMessage":"this object has not offer method javascript to call , please check addJavascriptInterface annotation was be added","messagePattern":"this object has not offer method javascript to call , please check addJavascriptInterface annotation was be added","errorType":"exception","errorClass":"JsInterfaceObjectException","httpStatus":null,"severity":"error","filePath":"agentweb-core/src/main/java/com/just/agentweb/JsInterfaceHolderImpl.java","lineNumber":73,"sourceCode":"            Object v = mEntry.getValue();\n            boolean t = checkObject(v);\n            if (!t) {\n                throw new JsInterfaceObjectException(\"This object has not offer method javascript to call ,please check addJavascriptInterface annotation was be added\");\n            } else {\n                addJavaObjectDirect(mEntry.getKey(), v);\n            }\n        }\n        return this;\n    }\n\n    @Override\n    public JsInterfaceHolder addJavaObject(String k, Object v) {\n        if (!checkSecurity()) {\n            return this;\n        }\n        boolean t = checkObject(v);\n        if (!t) {\n            throw new JsInterfaceObjectException(\"this object has not offer method javascript to call , please check addJavascriptInterface annotation was be added\");\n        } else {\n            addJavaObjectDirect(k, v);\n        }\n        return this;\n    }\n\n    private JsInterfaceHolder addJavaObjectDirect(String k, Object v) {\n        LogUtils.i(TAG, \"k:\" + k + \"  v:\" + v);\n        this.mWebView.addJavascriptInterface(v, k);\n        return this;\n    }\n\n}\n","sourceCodeStart":55,"sourceCodeEnd":87,"githubUrl":"https://github.com/Justson/AgentWeb/blob/8f7f6adbf01010e9b2b44638f31edf10e1ba53f7/agentweb-core/src/main/java/com/just/agentweb/JsInterfaceHolderImpl.java#L55-L87","documentation":"JsInterfaceHolderImpl.addJavaObject performs the same checkObject() validation as the bulk variant: the object must have @JavascriptInterface-annotated methods. If checkSecurity() passes but the object has no annotated methods, JsInterfaceObjectException is thrown. Note that if checkSecurity() fails the method silently returns without adding, so this exception only fires when security checks pass.","triggerScenarios":"Calling holder.addJavaObject(name, obj) with an object whose class lacks public methods annotated with android.webkit.JavascriptInterface, or with a proxy/dynamic class where annotations are not visible.","commonSituations":"Registering lambdas or anonymous inner classes whose methods are not annotated, wrong annotation import, obfuscation (ProGuard/R8) stripping the @JavascriptInterface annotation at release builds.","solutions":["Add android.webkit.JavascriptInterface annotations to the public methods you want exposed","Keep the annotation with ProGuard rules: -keepclassmembers class * { @android.webkit.JavascriptInterface <methods>; } and -keepattributes JavascriptInterface","Verify at runtime in release builds — annotation stripping differs from debug","Expose a small dedicated bridge class instead of lambdas/anonymous classes"],"exampleFix":"// before\nholder.addJavaObject(\"app\", (Runnable) () -> {}); // throws\n// after\npublic class AppBridge {\n    @android.webkit.JavascriptInterface\n    public void notifyApp(String msg) { }\n}\nholder.addJavaObject(\"app\", new AppBridge());","handlingStrategy":"validation","validationCode":"if (!isJsBridgeObject(v)) { Log.w(TAG, \"skip non-bridge object \" + k); return; }","typeGuard":"boolean isJsBridgeObject(Object o) { if (o == null) return false; for (Method m : o.getClass().getMethods()) { if (m.isAnnotationPresent(android.webkit.JavascriptInterface.class)) return true; } return false; }","tryCatchPattern":"try { holder.addJavaObject(name, obj); } catch (JsInterfaceObjectException e) { Log.e(TAG, \"not a JS bridge object\", e); }","preventionTips":["Use explicit bridge classes, not lambdas","Verify in release builds that annotations survive R8","Add -keepattributes JavascriptInterface","Unit-test JS bridge registration in release variant"],"tags":["android","javascript-interface","annotation","proguard"],"backgroundTag":"invalid-argument-value","analyzedSha":"8f7f6adbf01010e9b2b44638f31edf10e1ba53f7","analyzedAt":"2026-09-11T10:05:24.337Z","contentChangedAt":"2026-09-11T10:05:24.337Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}