How to suppress UnknownHostException at runtime in a Java gRPC client

47 Views Asked by At

A service request is issued to some unresolvable host using the following java gRPC blocking stub:

ManagedChannel channel = ManagedChannelBuilder.forAddress("SomeUnknownHost", 12345)
                                                .usePlaintext()
                                                .build();
    MyServiceGrpc.MyServiceBlockingStub clientStub;
    clientStub = MyServiceGrpc.newBlockingStub(channel);
    clientStub.increment(Message.newBuilder()
                                .setNumber(1)
                                .build());

This causes an UnknownHostException thrown at runtime:

Mar 03, 2024 2:43:02 A.M. io.grpc.internal.ManagedChannelImpl$NameResolverListener handleErrorInSyncContext
WARNING: [Channel<1>: (SomeUnknownHost:12345)] Failed to resolve name. status=Status{code=UNAVAILABLE, description=Unable to resolve host UnknownHostException, cause=java.lang.RuntimeException: java.net.UnknownHostException: foobar: nodename nor servname provided, or not known
    at io.grpc.internal.DnsNameResolver.resolveAddresses(DnsNameResolver.java:223)
    at io.grpc.internal.DnsNameResolver.doResolve(DnsNameResolver.java:282)
    at io.grpc.internal.DnsNameResolver$Resolve.run(DnsNameResolver.java:318)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
    at java.base/java.lang.Thread.run(Thread.java:1589)
Caused by: java.net.UnknownHostException: SomeUnknownHost: nodename nor servname provided, or not known
    at java.base/java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method)
    at java.base/java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:52)
    at java.base/java.net.InetAddress$PlatformResolver.lookupByName(InetAddress.java:1059)
    at java.base/java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1673)
    at java.base/java.net.InetAddress$NameServiceAddresses.get(InetAddress.java:1003)
    at java.base/java.net.InetAddress.getAllByName0(InetAddress.java:1663)
    at java.base/java.net.InetAddress.getAllByName(InetAddress.java:1528)
    at io.grpc.internal.DnsNameResolver$JdkAddressResolver.resolveAddress(DnsNameResolver.java:632)
    at io.grpc.internal.DnsNameResolver.resolveAddresses(DnsNameResolver.java:219)
    ... 5 more

Carl Mastrangelo explained here that:

In gRPC, calls are "fail fast" by default, which means that in the event of a network failure, the call will be treated as a failure. You can override this behavior on the stub

public static final class MyServiceBlockingStub extends io.grpc.stub.AbstractStub<MyServiceBlockingStub> {
    private MyServiceBlockingStub(io.grpc.Channel channel) {
      super(channel);
    }

    private MyServiceBlockingStub(io.grpc.Channel channel,
        io.grpc.CallOptions callOptions) {
      super(channel, callOptions.withWaitForReady());
    }

    @java.lang.Override
    protected MyServiceBlockingStub build(io.grpc.Channel channel,
        io.grpc.CallOptions callOptions) {
      //System.out.println("WAIT-FOR-READY IS ON: " + callOptions.withWaitForReady().isWaitForReady());

      return new MyServiceBlockingStub(channel, callOptions.withWaitForReady());
    }

    public Message increment(Message request) {
      System.out.println("WAIT-FOR-READY IS ON: " + getCallOptions().withWaitForReady().isWaitForReady()); // TRUE
      return blockingUnaryCall(
          getChannel(), getIncrementMethod(), getCallOptions().withWaitForReady(), request);
    }
}

The proposed solution was to enable the Wait-for-Ready call option in the client stub. So I tried making those changes but an UnknownHostException is still thrown at runtime.

What do I need to do to suppress UnknownHostException at runtime in a Java gRPC client?

0

There are 0 best solutions below