[ 
https://issues.apache.org/jira/browse/GROOVY-11871?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18065228#comment-18065228
 ] 

ASF GitHub Bot commented on GROOVY-11871:
-----------------------------------------

Copilot commented on code in PR #2140:
URL: https://github.com/apache/groovy/pull/2140#discussion_r2921432290


##########
subprojects/groovy-console/src/main/groovy/groovy/console/ui/Console.groovy:
##########
@@ -378,6 +378,13 @@ class Console implements CaretListener, HyperlinkListener, 
ComponentListener, Fo
         } catch (ClassNotFoundException ignore) {
         }
 
+        // listen for Maven resolver events if the Maven console plugin is on 
the classpath
+        try {
+            def mavenPluginClass = 
Class.forName('groovy.console.ui.ConsoleMavenPlugin')
+            mavenPluginClass.getConstructor().newInstance().addListener(this)
+        } catch (ClassNotFoundException ignore) {

Review Comment:
   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.
   ```suggestion
           } catch (ReflectiveOperationException ignore) {
   ```



##########
versions.properties:
##########
@@ -48,6 +48,8 @@ junit5Platform=1.14.3
 log4j=1.2.17
 log4j2=2.25.3
 logback=1.5.27
+mavenResolverProvider=4.0.0-rc-5
+mavenResolverSupplier=2.0.16

Review Comment:
   The PR description says "Just a placeholder at the moment", but this PR 
introduces a new Maven-based Grape engine subproject plus CLI/console/test 
changes. Please update the PR description to reflect the implemented scope and 
any remaining TODOs so reviewers know what's intended for this change set.



##########
src/main/java/groovy/grape/Grape.java:
##########
@@ -119,9 +121,12 @@ public static void setDisableChecksums(boolean 
disableChecksums) {
     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) {
             }

Review Comment:
   `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.



##########
src/main/groovy/groovy/grape/GrapeUtil.groovy:
##########
@@ -0,0 +1,175 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.grape
+
+import groovy.transform.CompileStatic
+import org.apache.groovy.plugin.GroovyRunner
+import org.apache.groovy.plugin.GroovyRunnerRegistry
+import org.codehaus.groovy.reflection.CachedClass
+import org.codehaus.groovy.reflection.ClassInfo
+import org.codehaus.groovy.runtime.m12n.ExtensionModuleScanner
+import org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl
+
+import java.util.jar.JarFile
+import java.util.zip.ZipEntry
+import java.util.zip.ZipException
+import java.util.zip.ZipFile
+
+/**
+ * Utility methods shared between GrapeIvy and GrapeMaven implementations.
+ */
+@CompileStatic
+class GrapeUtil {
+
+    private static final String METAINF_PREFIX = 'META-INF/services/'
+    private static final String RUNNER_PROVIDER_CONFIG = GroovyRunner.name
+
+    /**
+     * Adds a URI to a classloader's classpath via reflection.
+     */
+    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())
+    }

Review Comment:
   `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`.



##########
src/test/groovy/org/codehaus/groovy/runtime/m12n/ExtensionModuleHelperForTests.groovy:
##########
@@ -53,7 +53,8 @@ final class ExtensionModuleHelperForTests {
         def ant = new AntBuilder()
         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]+\\]'
         ]

Review Comment:
   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.



##########
subprojects/groovy-grape-maven/build.gradle:
##########
@@ -0,0 +1,28 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+plugins {
+    id 'org.apache.groovy-library'
+}
+
+dependencies {
+    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}"

Review Comment:
   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.
   ```suggestion
       testRuntimeOnly "org.slf4j:slf4j-simple:${versions.slf4j}"
   ```





> Support Maven Resolver based version of Grapes
> ----------------------------------------------
>
>                 Key: GROOVY-11871
>                 URL: https://issues.apache.org/jira/browse/GROOVY-11871
>             Project: Groovy
>          Issue Type: Improvement
>            Reporter: Paul King
>            Priority: Major
>




--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to