{"record":{"id":"09d8efac63683b88","repo":"apache/cordova-android","slug":"failed-to-create-webview","errorCode":null,"errorMessage":"Failed to create webview. ","messagePattern":"Failed to create webview\\. ","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"critical","filePath":"framework/src/org/apache/cordova/CordovaWebViewImpl.java","lineNumber":84,"sourceCode":"    private boolean hasPausedEver;\n\n    // The URL passed to loadUrl(), not necessarily the URL of the current page.\n    String loadedUrl;\n\n    /** custom view created by the browser (a video player for example) */\n    private View mCustomView;\n    private WebChromeClient.CustomViewCallback mCustomViewCallback;\n\n    private Set<Integer> boundKeyCodes = new HashSet<Integer>();\n\n    public static CordovaWebViewEngine createEngine(Context context, CordovaPreferences preferences) {\n        String className = preferences.getString(\"webview\", SystemWebViewEngine.class.getCanonicalName());\n        try {\n            Class<?> webViewClass = Class.forName(className);\n            Constructor<?> constructor = webViewClass.getConstructor(Context.class, CordovaPreferences.class);\n            return (CordovaWebViewEngine) constructor.newInstance(context, preferences);\n        } catch (Exception e) {\n            throw new RuntimeException(\"Failed to create webview. \", e);\n        }\n    }\n\n    public CordovaWebViewImpl(CordovaWebViewEngine cordovaWebViewEngine) {\n        this.engine = cordovaWebViewEngine;\n    }\n\n    // Convenience method for when creating programmatically (not from Config.xml).\n    public void init(CordovaInterface cordova) {\n        init(cordova, new ArrayList<PluginEntry>(), new CordovaPreferences());\n    }\n\n    @SuppressLint(\"Assert\")\n    @Override\n    public void init(CordovaInterface cordova, List<PluginEntry> pluginEntries, CordovaPreferences preferences) {\n        if (this.cordova != null) {\n            throw new IllegalStateException();\n        }","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/apache/cordova-android/blob/7c1e190064e349ffa4bbc6ac37b77cd773e4dbd3/framework/src/org/apache/cordova/CordovaWebViewImpl.java#L66-L102","documentation":"Cordova instantiates its WebView engine reflectively. CordovaWebViewImpl.createEngine reads the <preference name=\"webview\"> value from config.xml (default: org.apache.cordova.engine.SystemWebViewEngine), loads that class with Class.forName, and calls its (Context, CordovaPreferences) constructor. Any failure in that chain — ClassNotFoundException (bad class name / plugin not on classpath), NoSuchMethodException (missing 2-arg constructor), ClassCastException, or an exception thrown inside the engine's own constructor — is rethrown wrapped in this RuntimeException.","triggerScenarios":"config.xml contains <preference name=\"webview\" value=\"com.example.MyEngine\"/> but the engine plugin providing that class was removed or never installed; the FQN has a typo; a custom engine class lacks a public constructor taking (Context, CordovaPreferences); the engine's constructor itself throws (missing dependency, unsupported Android version); R8/ProGuard strips or renames the engine class in a release build.","commonSituations":"A custom webview engine plugin (e.g. a Crosswalk-style or vendor WebView engine) is uninstalled while its config.xml preference remains; projects migrated between cordova-android majors carry stale preferences; engine plugin installed but incompatible with the current platform release; release builds obfuscating the reflectively-loaded class.","solutions":["Read the wrapped cause in the stack trace: ClassNotFoundException means the class name/plugin is wrong; InvocationTargetException means the engine's constructor threw — fix whatever its cause says.","If you do not need a custom engine, delete the <preference name=\"webview\" .../> line from config.xml so the default SystemWebViewEngine is used, then cordova prepare android.","If you do need it, reinstall the engine plugin (cordova plugin ls / cordova plugin add <engine-plugin>) and verify the preference value exactly matches the engine class's fully-qualified name.","For a custom engine, make the class public, implement CordovaWebViewEngine, and expose a public (Context, CordovaPreferences) constructor.","For minified release builds, add a ProGuard/R8 keep rule for the engine class and its constructor."],"exampleFix":"// before — config.xml references an engine whose plugin was removed\n<preference name=\"webview\" value=\"com.example.FastWebViewEngine\" />\n\n// after — option A: drop the preference and use the built-in engine\n<!-- default SystemWebViewEngine is used -->\n\n// after — option B: restore the class via its plugin\n// cordova plugin add cordova-plugin-fast-webview\n<preference name=\"webview\" value=\"com.example.FastWebViewEngine\" />","handlingStrategy":"try-catch","validationCode":"// Verify the configured engine class loads before creating the engine\nString engineClass = preferences.getString(\"webview\", SystemWebViewEngine.class.getCanonicalName());\ntry {\n    Class<?> cls = Class.forName(engineClass); // fails fast with a clear ClassNotFoundException\n    cls.getConstructor(Context.class, CordovaPreferences.class); // constructor present?\n} catch (ReflectiveOperationException e) {\n    throw new IllegalStateException(\"Webview engine class \" + engineClass + \" is not usable; check the <preference name=\\\"webview\\\"/> and the engine plugin install\", e);\n}","typeGuard":null,"tryCatchPattern":"try {\n    engine = CordovaWebViewImpl.createEngine(context, preferences);\n} catch (RuntimeException e) {\n    Throwable cause = e.getCause() != null ? e.getCause() : e;\n    if (cause instanceof ClassNotFoundException) {\n        // bad <preference name=\"webview\"> value or engine plugin missing — fix config.xml / reinstall plugin\n    } else if (cause instanceof NoSuchMethodException) {\n        // engine lacks the required (Context, CordovaPreferences) constructor\n    } else {\n        // engine constructor threw; inspect cause for the real failure\n    }\n    throw new IllegalStateException(\"Webview engine failed to initialize\", cause);\n}","preventionTips":["Add or remove the webview preference and its engine plugin together — never leave the preference pointing at an uninstalled class.","Keep custom engine classes public with a (Context, CordovaPreferences) constructor.","Add R8/ProGuard keep rules for reflectively-loaded engine classes before shipping release builds.","Run one debug build after any config.xml change that touches the webview preference."],"tags":["webview","reflection","config-xml","android","classloading"],"backgroundTag":"classnotfoundexception","analyzedSha":"7c1e190064e349ffa4bbc6ac37b77cd773e4dbd3","analyzedAt":"2026-08-22T04:57:58.868Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}