From 556b903f924a0f1081c11c87e90c20af61618408 Mon Sep 17 00:00:00 2001 From: ldetmer Date: Wed, 4 Feb 2026 13:08:16 -0500 Subject: [PATCH 1/5] fix: make FilesTaskV2 gradle 9 compatible --- .../jib/gradle/skaffold/FilesTaskV2.java | 106 +++++++++++++----- 1 file changed, 78 insertions(+), 28 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..402412f3fd 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 @@ -51,8 +51,6 @@ */ public class FilesTaskV2 extends DefaultTask { - private static final GradleVersion GRADLE_9 = GradleVersion.version("9.0"); - private final SkaffoldFilesOutput skaffoldFilesOutput = new SkaffoldFilesOutput(); @Nullable private JibExtension jibExtension; @@ -81,9 +79,9 @@ public void listFiles() throws IOException { // Add extra layer List extraDirectories = - jibExtension.getExtraDirectories().getPaths().stream() - .map(ExtraDirectoryParameters::getFrom) - .collect(Collectors.toList()); + jibExtension.getExtraDirectories().getPaths().stream() + .map(ExtraDirectoryParameters::getFrom) + .collect(Collectors.toList()); extraDirectories.stream().filter(Files::exists).forEach(skaffoldFilesOutput::addInput); // Find project dependencies @@ -91,16 +89,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()); } @@ -109,7 +107,7 @@ public void listFiles() throws IOException { // Add SNAPSHOT, non-project dependency jars for (File file : - project.getConfigurations().getByName(jibExtension.getConfigurationName().get())) { + project.getConfigurations().getByName(jibExtension.getConfigurationName().get())) { if (!projectDependencyJars.contains(file) && file.toString().contains("SNAPSHOT")) { skaffoldFilesOutput.addInput(file.toPath()); projectDependencyJars.add(file); // Add to set to avoid printing the same files twice @@ -142,13 +140,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) { - skaffoldFilesOutput.addBuild( - project.getGradle().getStartParameter().getSettingsFile().toPath()); - } else if (Files.exists(projectPath.resolve(Settings.DEFAULT_SETTINGS_FILE))) { - skaffoldFilesOutput.addBuild(projectPath.resolve(Settings.DEFAULT_SETTINGS_FILE)); - } + addSettingsFile(project, projectPath); // Add gradle.properties if (Files.exists(projectPath.resolve("gradle.properties"))) { @@ -156,6 +148,34 @@ private void addGradleFiles(Project project) { } } + /** + * Adds the settings.gradle file for a project. + * + *

Uses reflection to call getSettingsFile() for compatibility with both Gradle 6 and 9 + * (getSettingsFile() was removed in Gradle 9). + * + * @param project the project + * @param projectPath the project directory path + */ + private void addSettingsFile(Project project, Path projectPath) { + try { + Object startParameter = project.getGradle().getStartParameter(); + java.lang.reflect.Method getSettingsFileMethod = + startParameter.getClass().getMethod("getSettingsFile"); + File settingsFile = (File) getSettingsFileMethod.invoke(startParameter); + if (settingsFile != null) { + skaffoldFilesOutput.addBuild(settingsFile.toPath()); + } else if (Files.exists(projectPath.resolve(Settings.DEFAULT_SETTINGS_FILE))) { + skaffoldFilesOutput.addBuild(projectPath.resolve(Settings.DEFAULT_SETTINGS_FILE)); + } + } catch (ReflectiveOperationException e) { + // Fall back to default settings file location if reflection fails + if (Files.exists(projectPath.resolve(Settings.DEFAULT_SETTINGS_FILE))) { + skaffoldFilesOutput.addBuild(projectPath.resolve(Settings.DEFAULT_SETTINGS_FILE)); + } + } + } + /** * Prints build files, sources, and resources associated with a project. * @@ -167,19 +187,19 @@ private void addProjectFiles(Project project) { // Add sources + resources SourceSetContainer sourceSetContainer = - project.getExtensions().findByType(SourceSetContainer.class); + project.getExtensions().findByType(SourceSetContainer.class); if (sourceSetContainer != null) { SourceSet mainSourceSet = sourceSetContainer.findByName(SourceSet.MAIN_SOURCE_SET_NAME); if (mainSourceSet != null) { mainSourceSet - .getAllSource() - .getSourceDirectories() - .forEach( - sourceDirectory -> { - if (sourceDirectory.exists()) { - skaffoldFilesOutput.addInput(sourceDirectory.toPath()); - } - }); + .getAllSource() + .getSourceDirectories() + .forEach( + sourceDirectory -> { + if (sourceDirectory.exists()) { + skaffoldFilesOutput.addInput(sourceDirectory.toPath()); + } + }); } } } @@ -204,7 +224,7 @@ private Set findProjectDependencies(Project project) { // Search through all dependencies Configuration runtimeClasspath = - currentProject.getConfigurations().findByName(configurationName); + currentProject.getConfigurations().findByName(configurationName); if (runtimeClasspath != null) { for (Configuration configuration : runtimeClasspath.getHierarchy()) { for (Dependency dependency : configuration.getDependencies()) { @@ -212,7 +232,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 +242,34 @@ private Set findProjectDependencies(Project project) { } return projectDependencies; } -} + + /** + * Resolves a {@link ProjectDependency} to its corresponding {@link Project} instance. + * + *

Uses reflection to handle both Gradle 6 (getDependencyProject()) and Gradle 9+ (getPath()). + * + * @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) { + // Try getDependencyProject() first (Gradle 6-8) + try { + java.lang.reflect.Method getDependencyProjectMethod = + projectDependency.getClass().getMethod("getDependencyProject"); + return (Project) getDependencyProjectMethod.invoke(projectDependency); + } catch (ReflectiveOperationException e) { + // Fall through to getPath() approach (Gradle 9+) + } + + // Try getPath() approach (Gradle 9+) + try { + java.lang.reflect.Method getPathMethod = projectDependency.getClass().getMethod("getPath"); + String path = (String) getPathMethod.invoke(projectDependency); + return getProject().project(path); + } catch (ReflectiveOperationException ex) { + throw new RuntimeException( + "Failed to resolve dependent project from " + projectDependency, ex); + } + } +} \ No newline at end of file From b7e57b22f70995af36e9fbadee8042deadeda5d7 Mon Sep 17 00:00:00 2001 From: ldetmer Date: Wed, 4 Feb 2026 14:17:46 -0500 Subject: [PATCH 2/5] some clean up --- .../tools/jib/gradle/skaffold/FilesTaskV2.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 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 402412f3fd..0ce327eeeb 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 @@ -158,6 +158,7 @@ private void addGradleFiles(Project project) { * @param projectPath the project directory path */ private void addSettingsFile(Project project, Path projectPath) { + boolean settingsFileAdded = false; try { Object startParameter = project.getGradle().getStartParameter(); java.lang.reflect.Method getSettingsFileMethod = @@ -165,14 +166,15 @@ private void addSettingsFile(Project project, Path projectPath) { File settingsFile = (File) getSettingsFileMethod.invoke(startParameter); if (settingsFile != null) { skaffoldFilesOutput.addBuild(settingsFile.toPath()); - } else if (Files.exists(projectPath.resolve(Settings.DEFAULT_SETTINGS_FILE))) { - skaffoldFilesOutput.addBuild(projectPath.resolve(Settings.DEFAULT_SETTINGS_FILE)); + settingsFileAdded = true; } } catch (ReflectiveOperationException e) { - // Fall back to default settings file location if reflection fails - if (Files.exists(projectPath.resolve(Settings.DEFAULT_SETTINGS_FILE))) { - skaffoldFilesOutput.addBuild(projectPath.resolve(Settings.DEFAULT_SETTINGS_FILE)); - } + // Fall through to default settings file check + } + + // Fall back to default settings file location if not already added + if (!settingsFileAdded && Files.exists(projectPath.resolve(Settings.DEFAULT_SETTINGS_FILE))) { + skaffoldFilesOutput.addBuild(projectPath.resolve(Settings.DEFAULT_SETTINGS_FILE)); } } @@ -267,9 +269,9 @@ private Project getDependentProject(ProjectDependency projectDependency) { java.lang.reflect.Method getPathMethod = projectDependency.getClass().getMethod("getPath"); String path = (String) getPathMethod.invoke(projectDependency); return getProject().project(path); - } catch (ReflectiveOperationException ex) { + } catch (ReflectiveOperationException e) { throw new RuntimeException( - "Failed to resolve dependent project from " + projectDependency, ex); + "Failed to resolve dependent project from " + projectDependency, e); } } } \ No newline at end of file From 59e0889ba66a3ce14f3203c5e74182d2f8187167 Mon Sep 17 00:00:00 2001 From: ldetmer Date: Wed, 4 Feb 2026 14:19:55 -0500 Subject: [PATCH 3/5] fix formatting --- .../jib/gradle/skaffold/FilesTaskV2.java | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 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 0ce327eeeb..b118469369 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 @@ -41,7 +41,6 @@ import org.gradle.api.tasks.SourceSet; import org.gradle.api.tasks.SourceSetContainer; import org.gradle.api.tasks.TaskAction; -import org.gradle.util.GradleVersion; /** * Prints out changing source dependencies on a project. @@ -79,9 +78,9 @@ public void listFiles() throws IOException { // Add extra layer List extraDirectories = - jibExtension.getExtraDirectories().getPaths().stream() - .map(ExtraDirectoryParameters::getFrom) - .collect(Collectors.toList()); + jibExtension.getExtraDirectories().getPaths().stream() + .map(ExtraDirectoryParameters::getFrom) + .collect(Collectors.toList()); extraDirectories.stream().filter(Files::exists).forEach(skaffoldFilesOutput::addInput); // Find project dependencies @@ -98,7 +97,7 @@ public void listFiles() throws IOException { configurationName = "default"; } for (Configuration targetConfiguration : - dependentProject.getConfigurations().getByName(configurationName).getHierarchy()) { + dependentProject.getConfigurations().getByName(configurationName).getHierarchy()) { for (PublishArtifact artifact : targetConfiguration.getArtifacts()) { projectDependencyJars.add(artifact.getFile()); } @@ -107,7 +106,7 @@ public void listFiles() throws IOException { // Add SNAPSHOT, non-project dependency jars for (File file : - project.getConfigurations().getByName(jibExtension.getConfigurationName().get())) { + project.getConfigurations().getByName(jibExtension.getConfigurationName().get())) { if (!projectDependencyJars.contains(file) && file.toString().contains("SNAPSHOT")) { skaffoldFilesOutput.addInput(file.toPath()); projectDependencyJars.add(file); // Add to set to avoid printing the same files twice @@ -162,7 +161,7 @@ private void addSettingsFile(Project project, Path projectPath) { try { Object startParameter = project.getGradle().getStartParameter(); java.lang.reflect.Method getSettingsFileMethod = - startParameter.getClass().getMethod("getSettingsFile"); + startParameter.getClass().getMethod("getSettingsFile"); File settingsFile = (File) getSettingsFileMethod.invoke(startParameter); if (settingsFile != null) { skaffoldFilesOutput.addBuild(settingsFile.toPath()); @@ -189,19 +188,19 @@ private void addProjectFiles(Project project) { // Add sources + resources SourceSetContainer sourceSetContainer = - project.getExtensions().findByType(SourceSetContainer.class); + project.getExtensions().findByType(SourceSetContainer.class); if (sourceSetContainer != null) { SourceSet mainSourceSet = sourceSetContainer.findByName(SourceSet.MAIN_SOURCE_SET_NAME); if (mainSourceSet != null) { mainSourceSet - .getAllSource() - .getSourceDirectories() - .forEach( - sourceDirectory -> { - if (sourceDirectory.exists()) { - skaffoldFilesOutput.addInput(sourceDirectory.toPath()); - } - }); + .getAllSource() + .getSourceDirectories() + .forEach( + sourceDirectory -> { + if (sourceDirectory.exists()) { + skaffoldFilesOutput.addInput(sourceDirectory.toPath()); + } + }); } } } @@ -226,7 +225,7 @@ private Set findProjectDependencies(Project project) { // Search through all dependencies Configuration runtimeClasspath = - currentProject.getConfigurations().findByName(configurationName); + currentProject.getConfigurations().findByName(configurationName); if (runtimeClasspath != null) { for (Configuration configuration : runtimeClasspath.getHierarchy()) { for (Dependency dependency : configuration.getDependencies()) { @@ -258,7 +257,7 @@ private Project getDependentProject(ProjectDependency projectDependency) { // Try getDependencyProject() first (Gradle 6-8) try { java.lang.reflect.Method getDependencyProjectMethod = - projectDependency.getClass().getMethod("getDependencyProject"); + projectDependency.getClass().getMethod("getDependencyProject"); return (Project) getDependencyProjectMethod.invoke(projectDependency); } catch (ReflectiveOperationException e) { // Fall through to getPath() approach (Gradle 9+) @@ -271,7 +270,7 @@ private Project getDependentProject(ProjectDependency projectDependency) { return getProject().project(path); } catch (ReflectiveOperationException e) { throw new RuntimeException( - "Failed to resolve dependent project from " + projectDependency, e); + "Failed to resolve dependent project from " + projectDependency, e); } } -} \ No newline at end of file +} From cb7b4826e6f7c110d09c2e2a894320f595ae53be Mon Sep 17 00:00:00 2001 From: ldetmer Date: Wed, 4 Feb 2026 15:09:00 -0500 Subject: [PATCH 4/5] added more robust logic to determining error in gradle version --- .../cloud/tools/jib/gradle/skaffold/FilesTaskV2.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 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 b118469369..1f0738db2c 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 @@ -253,14 +253,17 @@ private Set findProjectDependencies(Project project) { * @return the resolved project * @throws RuntimeException if the dependent project could not be resolved */ - private Project getDependentProject(ProjectDependency projectDependency) { + private Project getDependentProject(ProjectDependency projectDependency) { // Try getDependencyProject() first (Gradle 6-8) try { java.lang.reflect.Method getDependencyProjectMethod = projectDependency.getClass().getMethod("getDependencyProject"); return (Project) getDependencyProjectMethod.invoke(projectDependency); - } catch (ReflectiveOperationException e) { + } catch (NoSuchMethodException e) { // Fall through to getPath() approach (Gradle 9+) + } catch (ReflectiveOperationException e) { + throw new RuntimeException( + "Failed to resolve dependent project from " + projectDependency, e); } // Try getPath() approach (Gradle 9+) From 8a52c51674a514984606259971d3b13c3a432661 Mon Sep 17 00:00:00 2001 From: ldetmer Date: Wed, 4 Feb 2026 15:13:35 -0500 Subject: [PATCH 5/5] fix formatting --- .../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 1f0738db2c..6a72637225 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 @@ -253,7 +253,7 @@ private Set findProjectDependencies(Project project) { * @return the resolved project * @throws RuntimeException if the dependent project could not be resolved */ - private Project getDependentProject(ProjectDependency projectDependency) { + private Project getDependentProject(ProjectDependency projectDependency) { // Try getDependencyProject() first (Gradle 6-8) try { java.lang.reflect.Method getDependencyProjectMethod =