Skip to content

Guard gRPC beans on grpc-netty instead of grpc-api#4190

Open
seonwooj0810 wants to merge 1 commit into
spring-cloud:mainfrom
seonwooj0810:fix/issue-4169-grpc-conditional-netty
Open

Guard gRPC beans on grpc-netty instead of grpc-api#4190
seonwooj0810 wants to merge 1 commit into
spring-cloud:mainfrom
seonwooj0810:fix/issue-4169-grpc-conditional-netty

Conversation

@seonwooj0810

Copy link
Copy Markdown

Fixes gh-4169

Problem

JsonToGrpcGatewayFilterFactory and GrpcSslConfigurer in GatewayAutoConfiguration are guarded with @ConditionalOnClass(name = "io.grpc.Channel"). However io.grpc.Channel ships in grpc-api, while both beans actually require grpc-netty classes:

  • GrpcSslConfigurer extends AbstractSslConfigurer<NettyChannelBuilder, ManagedChannel> and uses io.grpc.netty.GrpcSslContexts.
  • JsonToGrpcGatewayFilterFactory uses io.grpc.netty.NettyChannelBuilder.

grpc-netty, grpc-protobuf and grpc-stub are declared <optional> in the server module. When an application has grpc-api on the classpath (e.g. pulled in transitively by an unrelated dependency) but not grpc-netty, these beans are still created and fail with:

java.lang.NoClassDefFoundError: io/grpc/netty/NettyChannelBuilder

The only workaround today is to add the full grpc-netty dependency even when the gateway's gRPC support is never used (see also gh-2769).

Change

Switch the @ConditionalOnClass guards on both beans (and the matching AOT reflection-hint registration in ConfigurableHintsRegistrationProcessor) from io.grpc.Channel to io.grpc.netty.NettyChannelBuilder — a class that is actually used by both beans and the exact class reported missing. The beans now activate only when grpc-netty is present.

Scope is limited to the webflux server module; the webmvc variant has no equivalent gRPC auto-configuration.

Test evidence

Added GatewayAutoConfigurationTests#grpcBeansNotConfiguredWhenGrpcNettyAbsent, which hides io.grpc.netty.NettyChannelBuilder via FilteredClassLoader (simulating grpc-api present, grpc-netty absent) and asserts the context starts and neither gRPC bean is created.

  • With the fix: passes (beans back off cleanly).
  • Reverting the guards to io.grpc.Channel makes the test fail, with jsonToGRPCFilterFactory wrongly present — confirming it is a genuine regression test.
Tests run: 3, Failures: 0, Errors: 0, Skipped: 0
  -- in org.springframework.cloud.gateway.config.GatewayAutoConfigurationTests

(grpcBeansNotConfiguredWhenGrpcNettyAbsent, gRPCFiltersConfiguredWhenHTTP2Enabled, gRPCFiltersNotConfiguredWhenHTTP2Disabled)

mvn validate (spring-javaformat + checkstyle) passes on the module. Commit is DCO signed-off.

JsonToGrpcGatewayFilterFactory and GrpcSslConfigurer require grpc-netty
classes (io.grpc.netty.NettyChannelBuilder, io.grpc.netty.GrpcSslContexts),
but their @ConditionalOnClass guard only checked io.grpc.Channel, which
ships in grpc-api. When grpc-api is present on the classpath without
grpc-netty, the beans were created and failed with
NoClassDefFoundError: io/grpc/netty/NettyChannelBuilder.

Switch the @ConditionalOnClass guards (and the matching AOT reflection
hint registration) to io.grpc.netty.NettyChannelBuilder so the beans only
activate when grpc-netty is actually available.

Fixes spring-cloudgh-4169

Signed-off-by: seonwoo_jung <79202163+seonwooj0810@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GrpcSslConfigurer beans are activated when no grpc-netty is present

2 participants