grpc-java/examples
Eric Anderson 1fc4ab0bb2 LBs should avoid calling LBs after lb.shutdown()
LoadBalancers shouldn't be called after shutdown(), but RingHashLb could
have enqueued work to the SynchronizationContext that executed after
shutdown(). This commit fixes problems discovered when auditing all LBs
usage of the syncContext for that type of problem.

Similarly, PickFirstLb could have requested a new connection after
shutdown(). We want to avoid that sort of thing too.

RingHashLb's test changed from CONNECTING to TRANSIENT_FAILURE to get
the latest picker. Because two subchannels have failed it will be in
TRANSIENT_FAILURE. Previously the test was using an older picker with
out-of-date subchannelView, and the verifyConnection() was too imprecise
to notice it was creating the wrong subchannel.

As discovered in b/430347751, where ClusterImplLb was seeing a new
subchannel being called after the child LB was shutdown (the shutdown
itself had been caused by RingHashConfig not implementing equals() and
was fixed by a8de9f07ab, which caused ClusterResolverLb to replace its
state):

```
java.lang.NullPointerException
	at io.grpc.xds.ClusterImplLoadBalancer$ClusterImplLbHelper.createClusterLocalityFromAttributes(ClusterImplLoadBalancer.java:322)
	at io.grpc.xds.ClusterImplLoadBalancer$ClusterImplLbHelper.createSubchannel(ClusterImplLoadBalancer.java:236)
	at io.grpc.util.ForwardingLoadBalancerHelper.createSubchannel(ForwardingLoadBalancerHelper.java:47)
	at io.grpc.util.ForwardingLoadBalancerHelper.createSubchannel(ForwardingLoadBalancerHelper.java:47)
	at io.grpc.internal.PickFirstLeafLoadBalancer.createNewSubchannel(PickFirstLeafLoadBalancer.java:527)
	at io.grpc.internal.PickFirstLeafLoadBalancer.requestConnection(PickFirstLeafLoadBalancer.java:459)
	at io.grpc.internal.PickFirstLeafLoadBalancer.acceptResolvedAddresses(PickFirstLeafLoadBalancer.java:174)
	at io.grpc.xds.LazyLoadBalancer$LazyDelegate.activate(LazyLoadBalancer.java:64)
	at io.grpc.xds.LazyLoadBalancer$LazyDelegate.requestConnection(LazyLoadBalancer.java:97)
	at io.grpc.util.ForwardingLoadBalancer.requestConnection(ForwardingLoadBalancer.java:61)
	at io.grpc.xds.RingHashLoadBalancer$RingHashPicker.lambda$pickSubchannel$0(RingHashLoadBalancer.java:440)
	at io.grpc.SynchronizationContext.drain(SynchronizationContext.java:96)
	at io.grpc.SynchronizationContext.execute(SynchronizationContext.java:128)
	at io.grpc.xds.client.XdsClientImpl$ResourceSubscriber.onData(XdsClientImpl.java:817)
```
2025-07-17 12:56:33 +00:00
..
android Start 1.75.0 development cycle 2025-06-25 04:52:17 +00:00
example-alts Start 1.75.0 development cycle 2025-06-25 04:52:17 +00:00
example-debug Start 1.75.0 development cycle 2025-06-25 04:52:17 +00:00
example-dualstack Start 1.75.0 development cycle 2025-06-25 04:52:17 +00:00
example-gauth Start 1.75.0 development cycle 2025-06-25 04:52:17 +00:00
example-gcp-csm-observability Start 1.75.0 development cycle 2025-06-25 04:52:17 +00:00
example-gcp-observability Start 1.75.0 development cycle 2025-06-25 04:52:17 +00:00
example-hostname Start 1.75.0 development cycle 2025-06-25 04:52:17 +00:00
example-jwt-auth Start 1.75.0 development cycle 2025-06-25 04:52:17 +00:00
example-oauth Start 1.75.0 development cycle 2025-06-25 04:52:17 +00:00
example-opentelemetry Start 1.75.0 development cycle 2025-06-25 04:52:17 +00:00
example-orca Start 1.75.0 development cycle 2025-06-25 04:52:17 +00:00
example-reflection Start 1.75.0 development cycle 2025-06-25 04:52:17 +00:00
example-servlet Start 1.75.0 development cycle 2025-06-25 04:52:17 +00:00
example-tls Start 1.75.0 development cycle 2025-06-25 04:52:17 +00:00
example-xds Start 1.75.0 development cycle 2025-06-25 04:52:17 +00:00
gradle/wrapper Upgrade Gradle to 8.10.2 and upgrade plugins 2024-10-30 07:00:57 -07:00
src LBs should avoid calling LBs after lb.shutdown() 2025-07-17 12:56:33 +00:00
.bazelrc Upgrade Protobuf Java to 3.22.3 (aka 22.3) 2023-04-17 13:16:20 -07:00
BUILD.bazel examples: Fix WORKSPACE to allow referencing grpc-xds 2024-07-23 16:11:44 -07:00
MODULE.bazel Start 1.75.0 development cycle 2025-06-25 04:52:17 +00:00
README.md examples: Update in-process sources in examples (#11952) 2025-03-10 05:20:20 +00:00
WORKSPACE examples: Fix WORKSPACE to allow referencing grpc-xds 2024-07-23 16:11:44 -07:00
WORKSPACE.bzlmod examples: Add bzlmod support 2024-07-23 08:32:13 -07:00
build.gradle Start 1.75.0 development cycle 2025-06-25 04:52:17 +00:00
gradlew Bump to Gradle 7.3.3 2022-01-10 10:28:42 -08:00
gradlew.bat Bump to Gradle 7.3.3 2022-01-10 10:28:42 -08:00
logging.properties examples: add keepalive example (#9956) 2023-03-17 16:27:33 -07:00
pom.xml Start 1.75.0 development cycle 2025-06-25 04:52:17 +00:00
settings.gradle examples: Remove references to maven-central.storage-download.googleapis.com 2025-01-03 09:28:42 -08:00

README.md

gRPC Examples

The examples require grpc-java to already be built. You are strongly encouraged to check out a git release tag, since there will already be a build of gRPC available. Otherwise you must follow COMPILING.

You may want to read through the Quick Start before trying out the examples.

Basic examples

To build the examples

  1. Install gRPC Java library SNAPSHOT locally, including code generation plugin (Only need this step for non-released versions, e.g. master HEAD).

  2. From grpc-java/examples directory:

$ ./gradlew installDist

This creates the scripts hello-world-server, hello-world-client, route-guide-server, route-guide-client, etc. in the build/install/examples/bin/ directory that run the examples. Each example requires the server to be running before starting the client.

For example, to try the hello world example first run:

$ ./build/install/examples/bin/hello-world-server

And in a different terminal window run:

$ ./build/install/examples/bin/hello-world-client

That's it!

For more information, refer to gRPC Java's README and tutorial.

Maven

If you prefer to use Maven:

  1. Install gRPC Java library SNAPSHOT locally, including code generation plugin (Only need this step for non-released versions, e.g. master HEAD).

  2. Run in this directory:

$ mvn verify
$ # Run the server
$ mvn exec:java -Dexec.mainClass=io.grpc.examples.helloworld.HelloWorldServer
$ # In another terminal run the client
$ mvn exec:java -Dexec.mainClass=io.grpc.examples.helloworld.HelloWorldClient

Bazel

If you prefer to use Bazel:

$ bazel build :hello-world-server :hello-world-client
$ # Run the server
$ bazel-bin/hello-world-server
$ # In another terminal run the client
$ bazel-bin/hello-world-client

Other examples

Unit test examples

Examples for unit testing gRPC clients and servers are located in examples/src/test.

In general, we DO NOT allow overriding the client stub and we DO NOT support mocking final methods in gRPC-Java library. Users should be cautious that using tools like PowerMock or mockito-inline can easily break this rule of thumb. We encourage users to leverage InProcessTransport as demonstrated in the examples to write unit tests. InProcessTransport is light-weight and runs the server and client in the same process without any socket/TCP connection.

Mocking the client stub provides a false sense of security when writing tests. Mocking stubs and responses allows for tests that don't map to reality, causing the tests to pass, but the system-under-test to fail. The gRPC client library is complicated, and accurately reproducing that complexity with mocks is very hard. You will be better off and write less code by using InProcessTransport instead.

Example bugs not caught by mocked stub tests include:

  • Calling the stub with a null message
  • Not calling close()
  • Sending invalid headers
  • Ignoring deadlines
  • Ignoring cancellation

For testing a gRPC client, create the client with a real stub using an InProcessChannel, and test it against an InProcessServer with a mock/fake service implementation.

For testing a gRPC server, create the server as an InProcessServer, and test it against a real client stub with an InProcessChannel.

The gRPC-java library also provides a JUnit rule, GrpcCleanupRule, to do the graceful shutdown boilerplate for you.

Even more examples

A wide variety of third-party examples can be found here.