Skip to content

Commit 0e06bd5

Browse files
Fix gRPC auto-configuration when protobuf is used without gRPC
ProtobufPluginAction now checks whether any io.grpc dependency is declared before configuring the protoc-gen-grpc-java plugin. Previously the plugin was always registered, causing Gradle to resolve io.grpc:protoc-gen-grpc-java:null for projects that use protobuf but not gRPC (fixes gh-50822). spring-boot-grpc-test has been removed from spring-boot-test-classic- modules. Including it with transitive=false left GrpcServerStartedEvent off the classpath while GrpcPortInfoApplicationContextInitializer still referenced it as a generic type parameter, triggering TypeNotPresentException during Spring's listener introspection (fixes gh-50825). Signed-off-by: Ujjwal Chitransh <ujjwalchitransh1@gmail.com>
1 parent a01c754 commit 0e06bd5

4 files changed

Lines changed: 64 additions & 5 deletions

File tree

build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/ProtobufPluginAction.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.gradle.api.Plugin;
3131
import org.gradle.api.Project;
3232
import org.gradle.api.artifacts.Configuration;
33+
import org.gradle.api.artifacts.Dependency;
3334
import org.gradle.api.artifacts.DependencyResolveDetails;
3435
import org.gradle.api.artifacts.ModuleVersionSelector;
3536
import org.gradle.api.artifacts.component.ModuleComponentIdentifier;
@@ -62,11 +63,27 @@ public Class<? extends Plugin<? extends Project>> getPluginClass() {
6263
public void execute(Project project) {
6364
ProtobufExtension protobuf = project.getExtensions().getByType(ProtobufExtension.class);
6465
protobuf.protoc(this::configureProtoc);
65-
protobuf.plugins(this::configurePlugins);
66-
protobuf.generateProtoTasks(this::configureGenerateProtoTasks);
6766
project.getConfigurations()
6867
.named(this::isProtobufToolsLocator)
6968
.configureEach((configuration) -> configureProtobufToolsLocator(project, configuration));
69+
// gRPC plugin configuration is deferred so we can check if gRPC is actually
70+
// declared as a dependency before registering the protoc-gen-grpc-java artifact.
71+
// Without this guard, Gradle would try to resolve io.grpc:protoc-gen-grpc-java:null
72+
// for projects that use protobuf but not gRPC.
73+
project.afterEvaluate((p) -> {
74+
if (hasGrpcDependency(p)) {
75+
protobuf.plugins(this::configurePlugins);
76+
protobuf.generateProtoTasks(this::configureGenerateProtoTasks);
77+
}
78+
});
79+
}
80+
81+
private boolean hasGrpcDependency(Project project) {
82+
return project.getConfigurations()
83+
.stream()
84+
.flatMap((configuration) -> configuration.getDependencies().stream())
85+
.map(Dependency::getGroup)
86+
.anyMatch("io.grpc"::equals);
7087
}
7188

7289
private void configureProtoc(ExecutableLocator protoc) {

build-plugin/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/plugin/ProtobufPluginActionIntegrationTests.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,12 @@ void usesVersionOfProtocDependencyWhenSpecified() {
9494
void usesVersionOfGrpcPluginDependencyWhenSpecified() {
9595
assertThat(this.gradleBuild.build("dependencies", "--configuration", "protobufToolsLocator_grpc").getOutput())
9696
.contains("io.grpc:protoc-gen-grpc-java:1.78.0");
97+
}
9798

99+
@TestTemplate
100+
void doesNotConfigureGrpcWhenGrpcIsNotPresent() {
101+
assertThat(this.gradleBuild.build("grpcNotConfigured").getOutput())
102+
.contains("grpc tools locator present: false");
98103
}
99104

100105
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright 2012-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
plugins {
18+
id 'org.springframework.boot' version '{version}'
19+
id 'java'
20+
}
21+
22+
apply plugin: 'com.google.protobuf'
23+
24+
group = 'com.example'
25+
version = '0.0.1'
26+
27+
repositories {
28+
mavenCentral()
29+
}
30+
31+
dependencies {
32+
implementation("com.google.protobuf:protobuf-java:4.34.0")
33+
}
34+
35+
tasks.register("grpcNotConfigured") {
36+
doFirst {
37+
def hasGrpcToolsLocator = project.configurations.names.any { it == "protobufToolsLocator_grpc" }
38+
println "grpc tools locator present: $hasGrpcToolsLocator"
39+
}
40+
}

module/spring-boot-test-classic-modules/build.gradle

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,6 @@ dependencies {
6767
api(project(":module:spring-boot-graphql-test")) {
6868
transitive = false
6969
}
70-
api(project(":module:spring-boot-grpc-test")) {
71-
transitive = false
72-
}
7370
api(project(":module:spring-boot-jdbc-test")) {
7471
transitive = false
7572
}

0 commit comments

Comments
 (0)