From a07ff8ff08ede2a5384002901c8e12ea7619b8b3 Mon Sep 17 00:00:00 2001 From: Dennis Fricke Date: Fri, 3 Apr 2026 18:20:04 +0200 Subject: [PATCH 01/10] Remove internal DslObject API usage for Gradle 10 compatibility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The DslObject fallback in resolveSpotBugVersion() was unreachable dead code — when the SpotBugs plugin is present, its extension is always a CodeQualityExtension subclass handled by the public API path above. Replace with a simple default version fallback. --- .../java/io/freefair/gradle/plugins/lombok/LombokPlugin.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java b/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java index 5004f363f..8eb3d2e4a 100644 --- a/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java +++ b/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java @@ -13,11 +13,9 @@ import org.gradle.api.attributes.Category; import org.gradle.api.attributes.DocsType; import org.gradle.api.attributes.VerificationType; -import org.gradle.api.internal.plugins.DslObject; import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.plugins.JavaPluginExtension; import org.gradle.api.plugins.quality.CodeQualityExtension; -import org.gradle.api.provider.Property; import org.gradle.api.provider.Provider; import org.gradle.api.tasks.PathSensitivity; import org.gradle.api.tasks.SourceSet; @@ -143,8 +141,7 @@ private String resolveSpotBugVersion() { return ((CodeQualityExtension) spotbugsExtension).getToolVersion(); } - Property toolVersionProperty = (Property) new DslObject(spotbugsExtension).getAsDynamicObject().getProperty("toolVersion"); - return toolVersionProperty.get(); + return SPOTBUGS_DEFAULT_VERSION; } private void configureDelombokDefaults(Delombok delombok) { From 2e3c0681b61376fb928dd03bdaa20e55c8eacd95 Mon Sep 17 00:00:00 2001 From: Dennis Fricke Date: Fri, 10 Apr 2026 12:22:16 +0200 Subject: [PATCH 02/10] Read SpotBugs toolVersion via reflection for non-CodeQualityExtension types SpotBugsExtension does not extend CodeQualityExtension, so the instanceof check always fails. Use reflection to invoke getToolVersion() on the actual extension type, falling back to the default version only when reflection also fails. This preserves user-configured SpotBugs versions without depending on the SpotBugs Gradle plugin at compile time. --- .../gradle/plugins/lombok/LombokPlugin.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java b/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java index 8eb3d2e4a..989d410ac 100644 --- a/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java +++ b/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java @@ -131,6 +131,7 @@ private void configureForSpotbugs(JavaPluginExtension javaPluginExtension) { }); } + @SuppressWarnings("unchecked") private String resolveSpotBugVersion() { if (!project.getPlugins().hasPlugin("com.github.spotbugs")) { return SPOTBUGS_DEFAULT_VERSION; @@ -141,6 +142,19 @@ private String resolveSpotBugVersion() { return ((CodeQualityExtension) spotbugsExtension).getToolVersion(); } + try { + Object result = spotbugsExtension.getClass().getMethod("getToolVersion").invoke(spotbugsExtension); + if (result instanceof org.gradle.api.provider.Property) { + String version = ((org.gradle.api.provider.Property) result).getOrNull(); + if (version != null) { + return version; + } + } else if (result instanceof String) { + return (String) result; + } + } catch (ReflectiveOperationException ignored) { + } + return SPOTBUGS_DEFAULT_VERSION; } From 725a00d2d621995992576b692c02854f98c10097 Mon Sep 17 00:00:00 2001 From: Dennis Fricke Date: Fri, 17 Apr 2026 12:22:27 +0200 Subject: [PATCH 03/10] Remove unused VerificationType import MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes checkstyle violation introduced during merge conflict resolution — the import was kept from the PR branch but is not used in this branch's code. --- .../java/io/freefair/gradle/plugins/lombok/LombokPlugin.java | 1 - 1 file changed, 1 deletion(-) diff --git a/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java b/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java index 24a1ce0b0..a95247e0a 100644 --- a/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java +++ b/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java @@ -10,7 +10,6 @@ import org.gradle.api.artifacts.Configuration; import org.gradle.api.artifacts.Dependency; import org.gradle.api.attributes.DocsType; -import org.gradle.api.attributes.VerificationType; import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.plugins.JavaPluginExtension; import org.gradle.api.plugins.quality.CodeQualityExtension; From 625665b432dcc4e512ef971fa2286fb96828466c Mon Sep 17 00:00:00 2001 From: Dennis Fricke Date: Fri, 24 Apr 2026 12:13:49 +0200 Subject: [PATCH 04/10] Fix naming typo, narrow suppression scope, broaden catch clause MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rename spotbugConfigured → spotbugsConfigured for consistency - Move @SuppressWarnings("unchecked") from method to cast site - Catch ClassCastException alongside ReflectiveOperationException --- .../gradle/plugins/lombok/LombokPlugin.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java b/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java index a95247e0a..4501ec103 100644 --- a/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java +++ b/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java @@ -13,6 +13,7 @@ import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.plugins.JavaPluginExtension; import org.gradle.api.plugins.quality.CodeQualityExtension; +import org.gradle.api.provider.Property; import org.gradle.api.provider.Provider; import org.gradle.api.tasks.PathSensitivity; import org.gradle.api.tasks.SourceSet; @@ -45,7 +46,7 @@ public class LombokPlugin implements Plugin { private LombokBasePlugin lombokBasePlugin; private Project project; - private boolean spotbugConfigured; + private boolean spotbugsConfigured; @Override public void apply(Project project) { @@ -121,10 +122,10 @@ private void configureSourceSetDefaults(SourceSet sourceSet) { } private void configureForSpotbugs(JavaPluginExtension javaPluginExtension) { - if (spotbugConfigured) { + if (spotbugsConfigured) { return; } - spotbugConfigured = true; + spotbugsConfigured = true; javaPluginExtension.getSourceSets().all(sourceSet -> { // Use findByName: sourceSets.all also fires for source sets added later @@ -142,7 +143,6 @@ private void configureForSpotbugs(JavaPluginExtension javaPluginExtension) { }); } - @SuppressWarnings("unchecked") private String resolveSpotBugVersion() { if (!project.getPlugins().hasPlugin("com.github.spotbugs")) { return SPOTBUGS_DEFAULT_VERSION; @@ -156,14 +156,16 @@ private String resolveSpotBugVersion() { try { Object result = spotbugsExtension.getClass().getMethod("getToolVersion").invoke(spotbugsExtension); if (result instanceof org.gradle.api.provider.Property) { - String version = ((org.gradle.api.provider.Property) result).getOrNull(); + @SuppressWarnings("unchecked") + Property toolVersionProperty = (Property) result; + String version = toolVersionProperty.getOrNull(); if (version != null) { return version; } } else if (result instanceof String) { return (String) result; } - } catch (ReflectiveOperationException e) { + } catch (ReflectiveOperationException | ClassCastException e) { project.getLogger().warn("Could not resolve SpotBugs tool version via reflection; falling back to {}", SPOTBUGS_DEFAULT_VERSION, e); } From 73ee150e4d89eb8ded35e40693f39d12c450014e Mon Sep 17 00:00:00 2001 From: Dennis Fricke Date: Fri, 1 May 2026 12:07:40 +0200 Subject: [PATCH 05/10] Improve SpotBugs version reflection robustness - Use getOrElse() instead of getOrNull() to honour Property convention chain - Add setAccessible(true) for JVM module boundary safety - Add debug log for unexpected getToolVersion() return types --- .../freefair/gradle/plugins/lombok/LombokPlugin.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java b/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java index 4501ec103..19974163c 100644 --- a/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java +++ b/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java @@ -154,16 +154,18 @@ private String resolveSpotBugVersion() { } try { - Object result = spotbugsExtension.getClass().getMethod("getToolVersion").invoke(spotbugsExtension); + java.lang.reflect.Method method = spotbugsExtension.getClass().getMethod("getToolVersion"); + method.setAccessible(true); + Object result = method.invoke(spotbugsExtension); if (result instanceof org.gradle.api.provider.Property) { @SuppressWarnings("unchecked") Property toolVersionProperty = (Property) result; - String version = toolVersionProperty.getOrNull(); - if (version != null) { - return version; - } + return toolVersionProperty.getOrElse(SPOTBUGS_DEFAULT_VERSION); } else if (result instanceof String) { return (String) result; + } else { + project.getLogger().debug("resolveSpotBugVersion: getToolVersion() returned unexpected type {}; using default {}", + result == null ? "null" : result.getClass().getName(), SPOTBUGS_DEFAULT_VERSION); } } catch (ReflectiveOperationException | ClassCastException e) { project.getLogger().warn("Could not resolve SpotBugs tool version via reflection; falling back to {}", SPOTBUGS_DEFAULT_VERSION, e); From 54753227ca58a723f01720cfc46188cab3bc8bcc Mon Sep 17 00:00:00 2001 From: Dennis Fricke Date: Fri, 8 May 2026 12:08:08 +0200 Subject: [PATCH 06/10] fix: Rename resolveSpotBugVersion to resolveSpotbugsVersion, clean up reflection - Consistent naming with spotbugsConfigured field - Use imported Property type instead of fully-qualified name - Remove unnecessary setAccessible(true) for public method --- .../io/freefair/gradle/plugins/lombok/LombokPlugin.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java b/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java index 19974163c..74c038bbb 100644 --- a/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java +++ b/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java @@ -134,7 +134,7 @@ private void configureForSpotbugs(JavaPluginExtension javaPluginExtension) { .findByName(sourceSet.getCompileOnlyConfigurationName()); if (compileOnly != null) { compileOnly.withDependencies(deps -> { - String toolVersion = resolveSpotBugVersion(); + String toolVersion = resolveSpotbugsVersion(); deps.add(project.getDependencies().create( "com.github.spotbugs:spotbugs-annotations:" + toolVersion )); @@ -143,7 +143,7 @@ private void configureForSpotbugs(JavaPluginExtension javaPluginExtension) { }); } - private String resolveSpotBugVersion() { + private String resolveSpotbugsVersion() { if (!project.getPlugins().hasPlugin("com.github.spotbugs")) { return SPOTBUGS_DEFAULT_VERSION; } @@ -155,16 +155,15 @@ private String resolveSpotBugVersion() { try { java.lang.reflect.Method method = spotbugsExtension.getClass().getMethod("getToolVersion"); - method.setAccessible(true); Object result = method.invoke(spotbugsExtension); - if (result instanceof org.gradle.api.provider.Property) { + if (result instanceof Property) { @SuppressWarnings("unchecked") Property toolVersionProperty = (Property) result; return toolVersionProperty.getOrElse(SPOTBUGS_DEFAULT_VERSION); } else if (result instanceof String) { return (String) result; } else { - project.getLogger().debug("resolveSpotBugVersion: getToolVersion() returned unexpected type {}; using default {}", + project.getLogger().debug("resolveSpotbugsVersion: getToolVersion() returned unexpected type {}; using default {}", result == null ? "null" : result.getClass().getName(), SPOTBUGS_DEFAULT_VERSION); } } catch (ReflectiveOperationException | ClassCastException e) { From 9732a54c891d3bc1c91b3b355e9e51842fbd10ac Mon Sep 17 00:00:00 2001 From: Dennis Fricke Date: Fri, 15 May 2026 12:09:00 +0200 Subject: [PATCH 07/10] Clean up reflection-based SpotBugs version resolution MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add proper import for java.lang.reflect.Method instead of inline FQN. Downgrade catch-block logging from warn to info — the reflection failure is gracefully handled and warn-level with a stack trace is unnecessarily noisy for a safe fallback path. --- .../io/freefair/gradle/plugins/lombok/LombokPlugin.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java b/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java index 74c038bbb..c902d2dc0 100644 --- a/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java +++ b/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java @@ -13,6 +13,7 @@ import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.plugins.JavaPluginExtension; import org.gradle.api.plugins.quality.CodeQualityExtension; +import java.lang.reflect.Method; import org.gradle.api.provider.Property; import org.gradle.api.provider.Provider; import org.gradle.api.tasks.PathSensitivity; @@ -154,7 +155,7 @@ private String resolveSpotbugsVersion() { } try { - java.lang.reflect.Method method = spotbugsExtension.getClass().getMethod("getToolVersion"); + Method method = spotbugsExtension.getClass().getMethod("getToolVersion"); Object result = method.invoke(spotbugsExtension); if (result instanceof Property) { @SuppressWarnings("unchecked") @@ -167,7 +168,8 @@ private String resolveSpotbugsVersion() { result == null ? "null" : result.getClass().getName(), SPOTBUGS_DEFAULT_VERSION); } } catch (ReflectiveOperationException | ClassCastException e) { - project.getLogger().warn("Could not resolve SpotBugs tool version via reflection; falling back to {}", SPOTBUGS_DEFAULT_VERSION, e); + project.getLogger().info("Could not resolve SpotBugs tool version via reflection ({}); falling back to {}", + e.getMessage(), SPOTBUGS_DEFAULT_VERSION); } return SPOTBUGS_DEFAULT_VERSION; From 7e088eb6d96a179aa92e564d690d49d719940435 Mon Sep 17 00:00:00 2001 From: Dennis Fricke Date: Fri, 22 May 2026 12:09:08 +0200 Subject: [PATCH 08/10] Remove dead CodeQualityExtension branch and fix import ordering SpotBugsExtension no longer extends CodeQualityExtension since spotbugs-gradle-plugin 5.0+, making the instanceof check dead code. The reflection path already handles all real cases. Also moves java.lang.reflect.Method import to the correct java.* block and removes the now-unused CodeQualityExtension import. --- .../io/freefair/gradle/plugins/lombok/LombokPlugin.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java b/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java index c902d2dc0..46fe5c1f1 100644 --- a/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java +++ b/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java @@ -5,6 +5,9 @@ import io.freefair.gradle.plugins.lombok.tasks.LombokConfig; import io.freefair.gradle.plugins.lombok.tasks.LombokTask; import lombok.Getter; + +import java.lang.reflect.Method; + import org.gradle.api.Plugin; import org.gradle.api.Project; import org.gradle.api.artifacts.Configuration; @@ -12,8 +15,6 @@ import org.gradle.api.attributes.DocsType; import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.plugins.JavaPluginExtension; -import org.gradle.api.plugins.quality.CodeQualityExtension; -import java.lang.reflect.Method; import org.gradle.api.provider.Property; import org.gradle.api.provider.Provider; import org.gradle.api.tasks.PathSensitivity; @@ -150,9 +151,6 @@ private String resolveSpotbugsVersion() { } Object spotbugsExtension = project.getExtensions().getByName("spotbugs"); - if (spotbugsExtension instanceof CodeQualityExtension) { - return ((CodeQualityExtension) spotbugsExtension).getToolVersion(); - } try { Method method = spotbugsExtension.getClass().getMethod("getToolVersion"); From 7c5af5bc079324398429d627adc129bf59f89306 Mon Sep 17 00:00:00 2001 From: Dennis Fricke Date: Fri, 5 Jun 2026 12:06:17 +0200 Subject: [PATCH 09/10] Harden resolveSpotbugsVersion reflection fallback Guard extension lookup against UnknownDomainObjectException, unwrap InvocationTargetException cause for useful log messages. --- .../freefair/gradle/plugins/lombok/LombokPlugin.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java b/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java index 46fe5c1f1..b159341e7 100644 --- a/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java +++ b/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java @@ -150,7 +150,13 @@ private String resolveSpotbugsVersion() { return SPOTBUGS_DEFAULT_VERSION; } - Object spotbugsExtension = project.getExtensions().getByName("spotbugs"); + Object spotbugsExtension; + try { + spotbugsExtension = project.getExtensions().getByName("spotbugs"); + } catch (Exception e) { + project.getLogger().info("Could not find SpotBugs extension; falling back to {}", SPOTBUGS_DEFAULT_VERSION); + return SPOTBUGS_DEFAULT_VERSION; + } try { Method method = spotbugsExtension.getClass().getMethod("getToolVersion"); @@ -166,8 +172,9 @@ private String resolveSpotbugsVersion() { result == null ? "null" : result.getClass().getName(), SPOTBUGS_DEFAULT_VERSION); } } catch (ReflectiveOperationException | ClassCastException e) { + Throwable cause = e.getCause() != null ? e.getCause() : e; project.getLogger().info("Could not resolve SpotBugs tool version via reflection ({}); falling back to {}", - e.getMessage(), SPOTBUGS_DEFAULT_VERSION); + cause.getMessage(), SPOTBUGS_DEFAULT_VERSION); } return SPOTBUGS_DEFAULT_VERSION; From 32d17a0fa3bb3bc4e4ef45ebe848487c93fe4bf4 Mon Sep 17 00:00:00 2001 From: Dennis Fricke Date: Fri, 12 Jun 2026 15:13:18 +0200 Subject: [PATCH 10/10] fix: Harden resolveSpotbugsVersion() against blank strings and unchecked exceptions Guard Property and String return paths against blank/empty values that would produce malformed Maven coordinates. Widen catch clause from ClassCastException to RuntimeException to cover unchecked exceptions from Property.getOrElse(). --- .../io/freefair/gradle/plugins/lombok/LombokPlugin.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java b/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java index b159341e7..b3626e2a7 100644 --- a/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java +++ b/lombok-plugin/src/main/java/io/freefair/gradle/plugins/lombok/LombokPlugin.java @@ -164,14 +164,15 @@ private String resolveSpotbugsVersion() { if (result instanceof Property) { @SuppressWarnings("unchecked") Property toolVersionProperty = (Property) result; - return toolVersionProperty.getOrElse(SPOTBUGS_DEFAULT_VERSION); - } else if (result instanceof String) { - return (String) result; + String resolved = toolVersionProperty.getOrElse(SPOTBUGS_DEFAULT_VERSION); + return resolved.isBlank() ? SPOTBUGS_DEFAULT_VERSION : resolved; + } else if (result instanceof String version && !version.isBlank()) { + return version; } else { project.getLogger().debug("resolveSpotbugsVersion: getToolVersion() returned unexpected type {}; using default {}", result == null ? "null" : result.getClass().getName(), SPOTBUGS_DEFAULT_VERSION); } - } catch (ReflectiveOperationException | ClassCastException e) { + } catch (ReflectiveOperationException | RuntimeException e) { Throwable cause = e.getCause() != null ? e.getCause() : e; project.getLogger().info("Could not resolve SpotBugs tool version via reflection ({}); falling back to {}", cause.getMessage(), SPOTBUGS_DEFAULT_VERSION);