From 5ba76f199b501e786378510fd01056ddbf6eda47 Mon Sep 17 00:00:00 2001 From: Hans Puac Date: Fri, 9 Jan 2026 19:51:23 +0100 Subject: [PATCH 1/4] fix(gradle): ensure Gradle 9 compatibility in FilesTaskV2 Address the removal of ProjectDependency.getDependencyProject() in Gradle 9 by introducing a version-aware resolution strategy. Fixes #4469 --- .../jib/gradle/skaffold/FilesTaskV2.java | 43 ++++++++++++++++--- 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/skaffold/FilesTaskV2.java b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/skaffold/FilesTaskV2.java index e5e482d355..9f022b1a7c 100644 --- a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/skaffold/FilesTaskV2.java +++ b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/skaffold/FilesTaskV2.java @@ -91,16 +91,16 @@ public void listFiles() throws IOException { Set projectDependencyJars = new HashSet<>(); for (ProjectDependency projectDependency : projectDependencies) { - addProjectFiles(projectDependency.getDependencyProject()); + Project dependentProject = getDependentProject(projectDependency); + addProjectFiles(dependentProject); // Keep track of project dependency jars for filtering out later String configurationName = projectDependency.getTargetConfiguration(); if (configurationName == null) { configurationName = "default"; } - Project dependencyProject = projectDependency.getDependencyProject(); for (Configuration targetConfiguration : - dependencyProject.getConfigurations().getByName(configurationName).getHierarchy()) { + dependentProject.getConfigurations().getByName(configurationName).getHierarchy()) { for (PublishArtifact artifact : targetConfiguration.getArtifacts()) { projectDependencyJars.add(artifact.getFile()); } @@ -142,8 +142,7 @@ private void addGradleFiles(Project project) { skaffoldFilesOutput.addBuild(project.getBuildFile().toPath()); // Add settings.gradle - if (GradleVersion.current().compareTo(GRADLE_9) < 0 - && project.getGradle().getStartParameter().getSettingsFile() != null) { + if (isBeforeGradle9() && project.getGradle().getStartParameter().getSettingsFile() != null) { skaffoldFilesOutput.addBuild( project.getGradle().getStartParameter().getSettingsFile().toPath()); } else if (Files.exists(projectPath.resolve(Settings.DEFAULT_SETTINGS_FILE))) { @@ -212,7 +211,7 @@ private Set findProjectDependencies(Project project) { // If this is a project dependency, save it ProjectDependency projectDependency = (ProjectDependency) dependency; if (!projectDependencies.contains(projectDependency)) { - projects.push(projectDependency.getDependencyProject()); + projects.push(getDependentProject(projectDependency)); projectDependencies.add(projectDependency); } } @@ -222,4 +221,36 @@ private Set findProjectDependencies(Project project) { } return projectDependencies; } + + /** + * Resolves a {@link ProjectDependency} to its corresponding {@link Project} instance. + * + *

This method handles the removal of {@code ProjectDependency.getDependencyProject()} in + * Gradle 9.0 by falling back to {@code getPath()} and resolving it via the project hierarchy. + * + * @param projectDependency the project dependency to resolve + * @return the resolved project + * @throws RuntimeException if the dependent project could not be resolved + */ + private Project getDependentProject(ProjectDependency projectDependency) { + if (isBeforeGradle9()) { + return projectDependency.getDependencyProject(); + } + try { + String path = + (String) projectDependency.getClass().getMethod("getPath").invoke(projectDependency); + return getProject().project(path); + } catch (Exception ex) { + throw new RuntimeException("Failed to get dependent project from " + projectDependency, ex); + } + } + + /** + * Checks if the current Gradle version is older than 9.0. + * + * @return {@code true} if the current Gradle version is less than 9.0, {@code false} otherwise + */ + private static boolean isBeforeGradle9() { + return GradleVersion.current().compareTo(GRADLE_9) < 0; + } } From fdbeec35218a74dbf39af5d04359eb4eaae4dc23 Mon Sep 17 00:00:00 2001 From: Hans Puac Date: Fri, 9 Jan 2026 20:56:23 +0100 Subject: [PATCH 2/4] test(gradle): add compatibility test for Gradle 9.0 in FilesTaskV2 Add a new test case testFilesTask_multiProjectComplexService_gradle9 to FilesTaskV2Test that explicitly runs against Gradle 9.0 using Gradle TestKit. This ensures that the reflection-based project resolution logic introduced for Gradle 9+ compatibility is verified. Verifies #4469 --- .../jib/gradle/skaffold/FilesTaskV2Test.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/skaffold/FilesTaskV2Test.java b/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/skaffold/FilesTaskV2Test.java index 3df3a86154..f34e981a5d 100644 --- a/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/skaffold/FilesTaskV2Test.java +++ b/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/skaffold/FilesTaskV2Test.java @@ -46,6 +46,10 @@ public class FilesTaskV2Test { @ClassRule public static final TestProject multiTestProject = new TestProject("multi-service"); + @ClassRule + public static final TestProject multiTestProjectGradle9 = + new TestProject("multi-service").withGradleVersion("9.0"); + @ClassRule public static final TestProject platformProject = new TestProject("platform").withGradleVersion("5.2"); @@ -170,6 +174,35 @@ public void testFilesTask_platformProject() throws IOException { assertThat(result.getIgnore()).isEmpty(); } + @Test + public void testFilesTask_multiProjectComplexService_gradle9() throws IOException { + Path projectRoot = multiTestProjectGradle9.getProjectRoot(); + Path complexServiceRoot = projectRoot.resolve("complex-service"); + Path libRoot = projectRoot.resolve("lib"); + SkaffoldFilesOutput result = + new SkaffoldFilesOutput(verifyTaskSuccess(multiTestProjectGradle9, "complex-service")); + assertPathListsAreEqual( + ImmutableList.of( + projectRoot.resolve("build.gradle"), + projectRoot.resolve("settings.gradle"), + projectRoot.resolve("gradle.properties"), + complexServiceRoot.resolve("build.gradle"), + libRoot.resolve("build.gradle")), + result.getBuild()); + assertPathListsAreEqual( + ImmutableList.of( + complexServiceRoot.resolve("src/main/extra-resources-1"), + complexServiceRoot.resolve("src/main/extra-resources-2"), + complexServiceRoot.resolve("src/main/java"), + complexServiceRoot.resolve("src/main/other-jib"), + libRoot.resolve("src/main/resources"), + libRoot.resolve("src/main/java"), + complexServiceRoot.resolve( + "local-m2-repo/com/google/cloud/tools/tiny-test-lib/0.0.1-SNAPSHOT/tiny-test-lib-0.0.1-SNAPSHOT.jar")), + result.getInputs()); + assertThat(result.getIgnore()).isEmpty(); + } + @Test public void testFilesTast_withConfigModifiers() throws IOException { Path projectRoot = skaffoldTestProject.getProjectRoot(); From e6705cc3eb51059fb8872c6f33cce83463101991 Mon Sep 17 00:00:00 2001 From: Hans Puac Date: Fri, 9 Jan 2026 21:29:45 +0100 Subject: [PATCH 3/4] refactor(test): move Gradle 9 compatibility test to end of file --- .../jib/gradle/skaffold/FilesTaskV2Test.java | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/skaffold/FilesTaskV2Test.java b/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/skaffold/FilesTaskV2Test.java index f34e981a5d..3c35549813 100644 --- a/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/skaffold/FilesTaskV2Test.java +++ b/jib-gradle-plugin/src/test/java/com/google/cloud/tools/jib/gradle/skaffold/FilesTaskV2Test.java @@ -174,6 +174,25 @@ public void testFilesTask_platformProject() throws IOException { assertThat(result.getIgnore()).isEmpty(); } + @Test + public void testFilesTast_withConfigModifiers() throws IOException { + Path projectRoot = skaffoldTestProject.getProjectRoot(); + SkaffoldFilesOutput result = + new SkaffoldFilesOutput(verifyTaskSuccess(skaffoldTestProject, null)); + assertPathListsAreEqual( + ImmutableList.of(projectRoot.resolve("build.gradle"), projectRoot.resolve("script.gradle")), + result.getBuild()); + assertPathListsAreEqual( + ImmutableList.of( + projectRoot.resolve("src/main/resources"), + projectRoot.resolve("src/main/java"), + projectRoot.resolve("src/main/jib"), + projectRoot.resolve("other/file.txt")), + result.getInputs()); + assertPathListsAreEqual( + ImmutableList.of(projectRoot.resolve("src/main/jib/bar")), result.getIgnore()); + } + @Test public void testFilesTask_multiProjectComplexService_gradle9() throws IOException { Path projectRoot = multiTestProjectGradle9.getProjectRoot(); @@ -202,23 +221,4 @@ public void testFilesTask_multiProjectComplexService_gradle9() throws IOExceptio result.getInputs()); assertThat(result.getIgnore()).isEmpty(); } - - @Test - public void testFilesTast_withConfigModifiers() throws IOException { - Path projectRoot = skaffoldTestProject.getProjectRoot(); - SkaffoldFilesOutput result = - new SkaffoldFilesOutput(verifyTaskSuccess(skaffoldTestProject, null)); - assertPathListsAreEqual( - ImmutableList.of(projectRoot.resolve("build.gradle"), projectRoot.resolve("script.gradle")), - result.getBuild()); - assertPathListsAreEqual( - ImmutableList.of( - projectRoot.resolve("src/main/resources"), - projectRoot.resolve("src/main/java"), - projectRoot.resolve("src/main/jib"), - projectRoot.resolve("other/file.txt")), - result.getInputs()); - assertPathListsAreEqual( - ImmutableList.of(projectRoot.resolve("src/main/jib/bar")), result.getIgnore()); - } } From a3d1cac7e1cc4550d5ca491e15be99f7e91557b9 Mon Sep 17 00:00:00 2001 From: Hans Puac Date: Fri, 9 Jan 2026 21:36:18 +0100 Subject: [PATCH 4/4] fix(gradle): use specific exception type in reflective call --- .../com/google/cloud/tools/jib/gradle/skaffold/FilesTaskV2.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/skaffold/FilesTaskV2.java b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/skaffold/FilesTaskV2.java index 9f022b1a7c..116c7a18f7 100644 --- a/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/skaffold/FilesTaskV2.java +++ b/jib-gradle-plugin/src/main/java/com/google/cloud/tools/jib/gradle/skaffold/FilesTaskV2.java @@ -240,7 +240,7 @@ private Project getDependentProject(ProjectDependency projectDependency) { String path = (String) projectDependency.getClass().getMethod("getPath").invoke(projectDependency); return getProject().project(path); - } catch (Exception ex) { + } catch (ReflectiveOperationException ex) { throw new RuntimeException("Failed to get dependent project from " + projectDependency, ex); } }