code: void advancedAsyncCall() {
      ClientCall<HelloRequest, HelloReply> call =
          channel.newCall(GreeterGrpc.getSayHelloMethod(), CallOptions.DEFAULT);
  
      final CountDownLatch latch = new CountDownLatch(1);
  
      call.start(new ClientCall.Listener<HelloReply>() {
  
        @Override
        public void onClose(Status status, Metadata trailers) {
          Verify.verify(status.getCode() == Status.Code.INTERNAL);
          Verify.verify(status.getDescription().contains("Narwhal"));
          // Cause is not transmitted over the wire.
          latch.countDown();
        }
      }, new Metadata());
  
      call.sendMessage(HelloRequest.newBuilder().setName("Marge").build());
      call.halfClose();
  
      if (!Uninterruptibles.awaitUninterruptibly(latch, 1, TimeUnit.SECONDS)) {
        throw new RuntimeException("timeout!");
      }
    }
docs: This is more advanced and does not make use of the stub.  You should not normally need to do
  this, but here is how you would.