grpc-java/core
Kenji Kaneda c131d2dd14 core: Do not call startDeadlineTimer when is deadlineCancellationExecutor is null
We got a NullPointerException from ClientCallImpl#startDeadlineTimer
when a new Call is created after a Netty channel is terminated. Here
is a stacktrace:

INTERNAL: java.lang.NullPointerException
at io.grpc.internal.ClientCallImpl.startDeadlineTimer(ClientCallImpl.java:320)
at io.grpc.internal.ClientCallImpl.start(ClientCallImpl.java:253)

The following code snippet reproduces the bug:

```
ManagedChannel channel = NettyChannelBuilder.forAddress(host, port)
    .usePlaintext(true)
    .build();
channel.shutdown();

Thread.sleep(1000);

GreeterGrpc.GreeterBlockingStub stub =
GreeterGrpc.newBlockingStub(channel)
    .withDeadlineAfter(10, TimeUnit.SECONDS);
stub.sayHello(HelloRequest.newBuilder().setName("world").build());
```

The issue was that ClientCallImpl is created from RealChannel#newCall
*after* ManagedChannelImpl#maybeTerminateChannel is called and
scheduledExecutor is set to null. In such a scenario,
deadlineCancellationExecutor is set to null.

I think there are several ways to fix this, but one way would be to
just avoid calling startDeadlineTimer() when
deadlineCancellationExecutor is null. DelayedClientTransport will
create a FailingClientStream with Status.UNAVAILABLE and we will get

```
Exception in thread "main" io.grpc.StatusRuntimeException:
UNAVAILABLE: Channel has shutdown (reported by delayed transport)
```
2017-03-28 16:31:29 -07:00
..
src core: Do not call startDeadlineTimer when is deadlineCancellationExecutor is null 2017-03-28 16:31:29 -07:00
build.gradle all: swap to newer animalsniffer plugin 2017-02-07 12:49:01 -08:00