{"record":{"id":"19bd3a3d02e798da","repo":"grpc/grpc-java","slug":"okhttpchannelbuilder-not-found-on-the-classpath","errorCode":null,"errorMessage":"OkHttpChannelBuilder not found on the classpath","messagePattern":"OkHttpChannelBuilder not found on the classpath","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"android/src/main/java/io/grpc/android/UdsChannelBuilder.java","lineNumber":69,"sourceCode":"  @SuppressWarnings(\"rawtypes\")\n  private static Class<? extends ManagedChannelBuilder> findOkHttp() {\n    try {\n      return Class.forName(\"io.grpc.okhttp.OkHttpChannelBuilder\")\n          .asSubclass(ManagedChannelBuilder.class);\n    } catch (ClassNotFoundException e) {\n      return null;\n    }\n  }\n\n  /**\n   * Returns a channel to the UDS endpoint specified by the file-path.\n   *\n   * @param path unix file system path to use for Unix Domain Socket.\n   * @param namespace the type of the namespace that the path belongs to.\n   */\n  public static ManagedChannelBuilder<?> forPath(String path, Namespace namespace) {\n    if (OKHTTP_CHANNEL_BUILDER_CLASS == null) {\n      throw new UnsupportedOperationException(\"OkHttpChannelBuilder not found on the classpath\");\n    }\n    try {\n      // Target 'dns:///127.0.0.1' is unused, but necessary as an argument for OkHttpChannelBuilder.\n      // An IP address is used instead of localhost to avoid a DNS lookup (see #11442). This should\n      // work even if IPv4 is unavailable, as the DNS resolver doesn't need working IPv4 to parse an\n      // IPv4 address. Unavailable IPv4 fails when we connect(), not at resolution time.\n      // TLS is unsupported because Conscrypt assumes the platform Socket implementation to improve\n      // performance by using the file descriptor directly.\n      Object o = OKHTTP_CHANNEL_BUILDER_CLASS\n          .getMethod(\"forTarget\", String.class, ChannelCredentials.class)\n          .invoke(null, \"dns:///127.0.0.1\", InsecureChannelCredentials.create());\n      ManagedChannelBuilder<?> builder = OKHTTP_CHANNEL_BUILDER_CLASS.cast(o);\n      OKHTTP_CHANNEL_BUILDER_CLASS\n          .getMethod(\"socketFactory\", SocketFactory.class)\n          .invoke(builder, new UdsSocketFactory(path, namespace));\n      return builder.proxyDetector(GrpcUtil.NOOP_PROXY_DETECTOR);\n    } catch (IllegalAccessException e) {\n      throw new RuntimeException(\"Failed to create OkHttpChannelBuilder\", e);","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/android/src/main/java/io/grpc/android/UdsChannelBuilder.java#L51-L87","documentation":"UdsChannelBuilder.forPath() builds UDS channels by reflectively loading io.grpc.okhttp.OkHttpChannelBuilder and injecting a UdsSocketFactory into it. If the grpc-okhttp artifact is not on the classpath, the static Class.forName lookup in findOkHttp() returns null and forPath() throws this UnsupportedOperationException immediately. The UDS transport simply cannot work without the OkHttp transport implementation present.","triggerScenarios":"Calling UdsChannelBuilder.forPath(path, namespace) at runtime in an app whose dependency set does not include io.grpc:grpc-okhttp, so the static initializer found no OkHttpChannelBuilder class.","commonSituations":"Android apps that added grpc-android but ProGuard/R8 stripped or the build excluded grpc-okhttp; projects that switched to another transport (e.g. Netty on server, or cronet) and assumed UdsChannelBuilder was transport-agnostic; missing transitive dependency after dependency tree pruning.","solutions":["Add the grpc-okhttp dependency (implementation 'io.grpc:grpc-okhttp:<matching grpc version>') to the app module.","Check ProGuard/R8 keep rules so io.grpc.okhttp.** is not stripped from the release build.","Verify the grpc-okhttp version matches the rest of the grpc-* artifacts to avoid mixed-version classpath issues.","If UDS support is not needed, use a regular ManagedChannelBuilder instead of UdsChannelBuilder.forPath()."],"exampleFix":"// before\ndependencies {\n    implementation 'io.grpc:grpc-android:1.50.0'\n}\n// after\ndependencies {\n    implementation 'io.grpc:grpc-android:1.50.0'\n    implementation 'io.grpc:grpc-okhttp:1.50.0'\n}","handlingStrategy":"fallback","validationCode":"try {\n  Class.forName(\"io.grpc.okhttp.OkHttpChannelBuilder\");\n} catch (ClassNotFoundException e) {\n  throw new IllegalStateException(\"grpc-okhttp missing from classpath; add io.grpc:grpc-okhttp\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  channel = UdsChannelBuilder.forPath(path, Namespace.FILESYSTEM).build();\n} catch (UnsupportedOperationException e) {\n  // grpc-okhttp not on classpath: fall back to TCP channel\n  channel = ManagedChannelBuilder.forAddress(host, port).usePlaintext().build();\n}","preventionTips":["Always ship io.grpc:grpc-okhttp alongside grpc-android when using UdsChannelBuilder.","Add a unit test that calls Class.forName(\"io.grpc.okhttp.OkHttpChannelBuilder\") to fail fast on dependency pruning.","Add ProGuard keep rules for io.grpc.okhttp.** and verify release builds.","Align all grpc-* artifacts with the grpc-bom to avoid version drift."],"tags":["grpc","android","classpath","missing-dependency","unix-domain-socket"],"backgroundTag":"missing-dependency","analyzedSha":"64daddc1f3d1975670f769f3e97bde8b2ba32d25","analyzedAt":"2026-09-08T06:14:57.704Z","contentChangedAt":"2026-09-08T06:14:57.704Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}