{"record":{"id":"1c27df655cc79caf","repo":"google/ExoPlayer","slug":"error-instantiating-vp9-extension","errorCode":null,"errorMessage":"Error instantiating VP9 extension","messagePattern":"Error instantiating VP9 extension","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"critical","filePath":"library/core/src/main/java/com/google/android/exoplayer2/DefaultRenderersFactory.java","lineNumber":407,"sourceCode":"          clazz.getConstructor(\n              long.class,\n              android.os.Handler.class,\n              com.google.android.exoplayer2.video.VideoRendererEventListener.class,\n              int.class);\n      Renderer renderer =\n          (Renderer)\n              constructor.newInstance(\n                  allowedVideoJoiningTimeMs,\n                  eventHandler,\n                  eventListener,\n                  MAX_DROPPED_VIDEO_FRAME_COUNT_TO_NOTIFY);\n      out.add(extensionRendererIndex++, renderer);\n      Log.i(TAG, \"Loaded LibvpxVideoRenderer.\");\n    } catch (ClassNotFoundException e) {\n      // Expected if the app was built without the extension.\n    } catch (Exception e) {\n      // The extension is present, but instantiation failed.\n      throw new RuntimeException(\"Error instantiating VP9 extension\", e);\n    }\n\n    try {\n      // Full class names used for constructor args so the LINT rule triggers if any of them move.\n      Class<?> clazz = Class.forName(\"com.google.android.exoplayer2.ext.av1.Libgav1VideoRenderer\");\n      Constructor<?> constructor =\n          clazz.getConstructor(\n              long.class,\n              android.os.Handler.class,\n              com.google.android.exoplayer2.video.VideoRendererEventListener.class,\n              int.class);\n      Renderer renderer =\n          (Renderer)\n              constructor.newInstance(\n                  allowedVideoJoiningTimeMs,\n                  eventHandler,\n                  eventListener,\n                  MAX_DROPPED_VIDEO_FRAME_COUNT_TO_NOTIFY);","sourceCodeStart":389,"sourceCodeEnd":425,"githubUrl":"https://github.com/google/ExoPlayer/blob/dd430f7053a1a3958deea3ead6a0565150c06bfc/library/core/src/main/java/com/google/android/exoplayer2/DefaultRenderersFactory.java#L389-L425","documentation":"DefaultRenderersFactory reflectively loads the optional VP9 extension renderer (com.google.android.exoplayer2.ext.vp9.LibvpxVideoRenderer) when an extension renderer mode beyond OFF is set. ClassNotFoundException is treated as 'extension not built' and silently ignored, but any other reflective failure (NoSuchMethodException, IllegalAccessException, InvocationTargetException from a constructor crash) means the extension classes are on the classpath yet broken, so the factory aborts by wrapping the cause in a RuntimeException. This is a fail-fast guard: a half-present extension would otherwise cause subtle runtime decoder failures later.","triggerScenarios":"Building the player with DefaultRenderersFactory.EXTENSION_RENDERER_MODE_ON (or PREFER) while the vp9 extension AAR/module is on the classpath but its renderer constructor signature does not match the one looked up (long, Handler, VideoRendererEventListener, int), or the renderer constructor itself throws (e.g. its native libvpx library failed to load via System.loadLibrary).","commonSituations":"Mixing extension and core versions from different ExoPlayer releases (constructor args changed between versions); a ProGuard/R8 pass that renamed or stripped constructor parameter types; an APK built with a vp9 .so missing for the device ABI; reflective access blocked on newer JDK/Android (module restrictions).","solutions":["Check the chained cause in the RuntimeException (e.getCause()) — it names the real failure such as UnsatisfiedLinkError or NoSuchMethodException.","Ensure the exoplayer-vp9 extension artifact version exactly matches the core library version.","Keep ProGuard/R8 from obfuscating or removing extension classes and their constructor signatures (add keep rules for com.google.android.exoplayer2.ext.**).","If you do not need VP9 software decoding, build with EXTENSION_RENDERER_MODE_OFF so the reflective block is skipped entirely."],"exampleFix":"// before\nDefaultRenderersFactory factory =\n    new DefaultRenderersFactory(context)\n        .setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_ON);\n\n// after — only enable extensions when the matching extension build is packaged\nDefaultRenderersFactory factory =\n    new DefaultRenderersFactory(context)\n        .setExtensionRendererMode(\n            BuildConfig.USE_VPX_EXTENSION\n                ? DefaultRenderersFactory.EXTENSION_RENDERER_MODE_ON\n                : DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF);","handlingStrategy":"try-catch","validationCode":"Class<?> clazz;\ntry {\n  clazz = Class.forName(\"com.google.android.exoplayer2.ext.vp9.LibvpxVideoRenderer\");\n} catch (ClassNotFoundException e) {\n  clazz = null;\n}\nboolean vp9ExtensionLoadable = false;\nif (clazz != null) {\n  try {\n    clazz.getConstructor(long.class, Handler.class,\n        VideoRendererEventListener.class, int.class);\n    vp9ExtensionLoadable = true;\n  } catch (NoSuchMethodException ignored) {\n  }\n}\nint mode = vp9ExtensionLoadable\n    ? DefaultRenderersFactory.EXTENSION_RENDERER_MODE_ON\n    : DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF;","typeGuard":null,"tryCatchPattern":"try {\n  player = new ExoPlayer.Builder(vp9Factory).build(context);\n} catch (RuntimeException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"VP9 extension\")) {\n    // extension present but broken: fall back to core renderers\n    player = new ExoPlayer.Builder(\n        new DefaultRenderersFactory(context)\n            .setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF))\n        .build(context);\n  } else { throw e; }\n}","preventionTips":["Pin exoplayer-core and every extension artifact to the identical version","Add R8 keep rules for com.google.android.exoplayer2.ext.** constructors","Run a smoke playback test on every release build type (not just debug)","Verify each target ABI has the extension .so in the final APK with the Bundletool APK analyzer"],"tags":["exoplayer","reflection","extension","vp9","renderer","initialization"],"backgroundTag":null,"analyzedSha":"dd430f7053a1a3958deea3ead6a0565150c06bfc","analyzedAt":"2026-08-14T12:22:02.982Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}