Skip to content

GROOVY-11871: Support Maven Resolver based version of Grapes#2140

Open
paulk-asert wants to merge 1 commit intoapache:masterfrom
paulk-asert:grapeMaven
Open

GROOVY-11871: Support Maven Resolver based version of Grapes#2140
paulk-asert wants to merge 1 commit intoapache:masterfrom
paulk-asert:grapeMaven

Conversation

@paulk-asert
Copy link
Contributor

@paulk-asert paulk-asert commented Jan 13, 2025

Provide an Apache Maven Resolver alternative backend implementation for Groovy Grapes.

@codecov-commenter
Copy link

codecov-commenter commented Mar 8, 2026

Codecov Report

❌ Patch coverage is 7.48441% with 445 lines in your changes missing coverage. Please review.
✅ Project coverage is 66.5293%. Comparing base (7d8349c) to head (4364f6f).
⚠️ Report is 13 commits behind head on master.

Files with missing lines Patch % Lines
...c/main/groovy/groovy/grape/maven/GrapeMaven.groovy 0.0000% 338 Missing ⚠️
src/main/groovy/groovy/grape/GrapeUtil.groovy 50.9091% 18 Missing and 9 partials ⚠️
src/main/groovy/groovy/grape/GrapeIvy.groovy 19.2308% 21 Missing ⚠️
.../groovy/org/codehaus/groovy/tools/GrapeMain.groovy 0.0000% 21 Missing ⚠️
...n/groovy/groovy/console/ui/ConsoleIvyPlugin.groovy 0.0000% 17 Missing ⚠️
...groovy/groovy/console/ui/ConsoleMavenPlugin.groovy 0.0000% 15 Missing ⚠️
src/main/java/groovy/grape/Grape.java 50.0000% 2 Missing and 1 partial ⚠️
...e/src/main/groovy/groovy/console/ui/Console.groovy 0.0000% 2 Missing ⚠️
src/main/java/groovy/grape/GrapeEngine.java 0.0000% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@                Coverage Diff                 @@
##               master      #2140        +/-   ##
==================================================
- Coverage     66.7571%   66.5293%   -0.2277%     
- Complexity      29856      29871        +15     
==================================================
  Files            1382       1386         +4     
  Lines          116130     116508       +378     
  Branches        20471      20603       +132     
==================================================
- Hits            77525      77512        -13     
- Misses          32275      32663       +388     
- Partials         6330       6333         +3     
Files with missing lines Coverage Δ
...-xml/src/main/groovy/groovy/xml/StaxBuilder.groovy 95.0000% <ø> (ø)
src/main/java/groovy/grape/GrapeEngine.java 0.0000% <0.0000%> (ø)
...e/src/main/groovy/groovy/console/ui/Console.groovy 0.0000% <0.0000%> (ø)
src/main/java/groovy/grape/Grape.java 29.0698% <50.0000%> (+0.6747%) ⬆️
...groovy/groovy/console/ui/ConsoleMavenPlugin.groovy 0.0000% <0.0000%> (ø)
...n/groovy/groovy/console/ui/ConsoleIvyPlugin.groovy 0.0000% <0.0000%> (ø)
src/main/groovy/groovy/grape/GrapeIvy.groovy 34.7962% <19.2308%> (-4.5200%) ⬇️
.../groovy/org/codehaus/groovy/tools/GrapeMain.groovy 0.0000% <0.0000%> (ø)
src/main/groovy/groovy/grape/GrapeUtil.groovy 50.9091% <50.9091%> (ø)
...c/main/groovy/groovy/grape/maven/GrapeMaven.groovy 0.0000% <0.0000%> (ø)

... and 15 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@paulk-asert paulk-asert changed the title early draft GROOVY-11871: Support Maven Resolver based version of Grapes Mar 9, 2026
@paulk-asert paulk-asert marked this pull request as ready for review March 9, 2026 08:37
@daniellansun daniellansun requested a review from Copilot March 10, 2026 01:22

This comment was marked as outdated.

This comment was marked as outdated.

This comment was marked as outdated.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 23 out of 24 changed files in this pull request and generated 6 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines 54 to 58
def allowed = [
'Picked up JAVA_TOOL_OPTIONS: .*',
'Picked up _JAVA_OPTIONS: .*'
'Picked up _JAVA_OPTIONS: .*',
'(?s)SLF4J\\(W\\): Class path contains multiple SLF4J providers\\..*SLF4J\\(I\\): Actual provider is of type \\[[^\\n]+\\]'
]
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test now whitelists the SLF4J "multiple providers" warning rather than preventing the duplicate providers from appearing on the forked classpath. If possible, prefer fixing the underlying classpath/provider selection (so warnings don't leak into user output) instead of accepting the warning as normal.

Copilot uses AI. Check for mistakes.
Comment on lines 121 to 131
public static synchronized GrapeEngine getInstance() {
if (instance == null) {
try {
// by default use GrapeIvy
String grapeClass = System.getProperty("groovy.grape.impl");
if (grapeClass == null) {
grapeClass = "groovy.grape.GrapeIvy"; // by default use GrapeIvy
}
// TODO: META-INF/services resolver?
instance = (GrapeEngine) Class.forName("groovy.grape.GrapeIvy").getDeclaredConstructor().newInstance();
instance = (GrapeEngine) Class.forName(grapeClass).getDeclaredConstructor().newInstance();
} catch (ReflectiveOperationException ignore) {
}
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getInstance() now instantiates the engine from the groovy.grape.impl system property, but any ReflectiveOperationException is silently swallowed, leaving instance as null and effectively disabling Grapes with no diagnostics. Consider falling back to the default engine (GrapeIvy) and/or throwing an IllegalStateException (or at least logging to stderr) so misconfiguration is discoverable.

Copilot uses AI. Check for mistakes.
Comment on lines +46 to +49
static void addURL(ClassLoader loader, URI uri) {
// Dynamic invocation needed as addURL is not part of ClassLoader interface
loader.metaClass.invokeMethod(loader, 'addURL', uri.toURL())
}
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GrapeUtil is @CompileStatic but addURL uses loader.metaClass.invokeMethod(...), which relies on Groovy's dynamic metaClass property and is likely to fail static compilation. Consider marking addURL as @CompileDynamic (as the old Ivy implementation did) or using a statically-compilable reflective call (e.g., via InvokerHelper/reflection) to invoke addURL.

Copilot uses AI. Check for mistakes.
api rootProject
implementation "org.apache.maven:maven-resolver-provider:${versions.mavenResolverProvider}"
implementation "org.apache.maven.resolver:maven-resolver-supplier-mvn4:${versions.mavenResolverSupplier}"
runtimeOnly "org.slf4j:slf4j-simple:${versions.slf4j}"
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Declaring slf4j-simple as runtimeOnly makes this library bring its own SLF4J provider, which can cause "multiple SLF4J providers" warnings and override an application's chosen logging backend. Consider making the backend a test-only dependency (e.g. testRuntimeOnly) or leaving provider selection to the consuming application.

Suggested change
runtimeOnly "org.slf4j:slf4j-simple:${versions.slf4j}"
testRuntimeOnly "org.slf4j:slf4j-simple:${versions.slf4j}"

Copilot uses AI. Check for mistakes.
try {
def mavenPluginClass = Class.forName('groovy.console.ui.ConsoleMavenPlugin')
mavenPluginClass.getConstructor().newInstance().addListener(this)
} catch (ClassNotFoundException ignore) {
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Maven console plugin is loaded reflectively but the code only catches ClassNotFoundException. If the class exists but fails to instantiate (e.g. constructor/initializer throws, missing dependencies, ReflectiveOperationException), Console startup will fail. Consider catching broader reflection exceptions here (similar to how optional integrations are typically guarded) and either ignoring or reporting a concise message.

Suggested change
} catch (ClassNotFoundException ignore) {
} catch (ReflectiveOperationException ignore) {

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants