This is an automated email from the ASF dual-hosted git repository. emilles pushed a commit to branch GROOVY-6491 in repository https://gitbox.apache.org/repos/asf/groovy.git
commit ab4fb07db16066b9e0f88bd7d6b622a45e6d67e7 Author: Eric Milles <[email protected]> AuthorDate: Wed Sep 17 09:57:56 2025 -0500 GROOVY-6491: empty extension module implies a restriction (like OSGi) --- .../runtime/m12n/ExtensionModuleScanner.java | 37 +++++++++++----------- .../m12n/StandardPropertiesModuleFactory.java | 15 +++++---- 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/main/java/org/codehaus/groovy/runtime/m12n/ExtensionModuleScanner.java b/src/main/java/org/codehaus/groovy/runtime/m12n/ExtensionModuleScanner.java index d15bc6437c..c7167643f9 100644 --- a/src/main/java/org/codehaus/groovy/runtime/m12n/ExtensionModuleScanner.java +++ b/src/main/java/org/codehaus/groovy/runtime/m12n/ExtensionModuleScanner.java @@ -23,12 +23,10 @@ import org.codehaus.groovy.runtime.DefaultGroovyMethods; import org.codehaus.groovy.util.URLStreams; import java.io.IOException; -import java.io.InputStream; import java.net.URL; +import java.util.Objects; import java.util.Properties; -import static org.codehaus.groovy.runtime.DefaultGroovyMethodsSupport.closeQuietly; - /** * A module extension scanner is responsible for searching classpath modules, * loading metadata from module descriptors, then perform custom tasks for each @@ -39,6 +37,7 @@ import static org.codehaus.groovy.runtime.DefaultGroovyMethodsSupport.closeQuiet * @since 2.1.2 */ public class ExtensionModuleScanner { + public static final String LEGACY_MODULE_META_INF_FILE = "META-INF/services/org.codehaus.groovy.runtime.ExtensionModule"; public static final String MODULE_META_INF_FILE = "META-INF/groovy/org.codehaus.groovy.runtime.ExtensionModule"; @@ -46,8 +45,8 @@ public class ExtensionModuleScanner { private final ClassLoader classLoader; public ExtensionModuleScanner(final ExtensionModuleListener listener, final ClassLoader loader) { - this.listener = listener; - this.classLoader = loader; + this.listener = Objects.requireNonNull(listener); + this.classLoader = Objects.requireNonNull(loader); } public void scanClasspathModules() { @@ -55,37 +54,39 @@ public class ExtensionModuleScanner { scanClasspathModulesFrom(LEGACY_MODULE_META_INF_FILE); } - private void scanClasspathModulesFrom(String moduleMetaInfFile) { + private void scanClasspathModulesFrom(final String moduleMetaInfFile) { try { for (URL url : DefaultGroovyMethods.toSet(classLoader.getResources(moduleMetaInfFile))) { scanExtensionModuleFromMetaInf(url); } - } catch (IOException e) { + } catch (final IOException e) { // DO NOTHING } } private void scanExtensionModuleFromMetaInf(final URL metadata) { Properties properties = new Properties(); - InputStream inStream = null; - try { - inStream = URLStreams.openUncachedStream(metadata); - properties.load(inStream); - } catch (IOException e) { + + try (var stream = URLStreams.openUncachedStream(metadata)) { + properties.load(stream); + } catch (final IOException e) { throw new GroovyRuntimeException("Unable to load module META-INF descriptor", e); - } finally { - closeQuietly(inStream); } + scanExtensionModuleFromProperties(properties); } public void scanExtensionModuleFromProperties(final Properties properties) { - StandardPropertiesModuleFactory factory = new StandardPropertiesModuleFactory(); - ExtensionModule module = factory.newModule(properties, classLoader); - listener.onModule(module); + var factory = new StandardPropertiesModuleFactory(); + var module = factory.newModule(properties, classLoader); + if (module instanceof SimpleExtensionModule simpleModule + && simpleModule.getStaticMethodsExtensionClasses().isEmpty() + && simpleModule.getInstanceMethodsExtensionClasses().isEmpty()) { + module = null; // GROOVY-6491: empty module implies restriction (like OSGi) + } + if (module != null) listener.onModule(module); } - public interface ExtensionModuleListener { void onModule(ExtensionModule module); } diff --git a/src/main/java/org/codehaus/groovy/runtime/m12n/StandardPropertiesModuleFactory.java b/src/main/java/org/codehaus/groovy/runtime/m12n/StandardPropertiesModuleFactory.java index 3c148b6830..6b89b369ff 100644 --- a/src/main/java/org/codehaus/groovy/runtime/m12n/StandardPropertiesModuleFactory.java +++ b/src/main/java/org/codehaus/groovy/runtime/m12n/StandardPropertiesModuleFactory.java @@ -30,24 +30,25 @@ import java.util.Properties; * factory is instantiated and used instead of this factory. */ public class StandardPropertiesModuleFactory extends PropertiesModuleFactory { + public static final String MODULE_FACTORY_KEY = "moduleFactory"; @Override @SuppressWarnings("unchecked") public ExtensionModule newModule(final Properties properties, final ClassLoader classLoader) { String factoryName = properties.getProperty(MODULE_FACTORY_KEY); - if (factoryName!=null) { + if (factoryName != null) { try { - Class<? extends PropertiesModuleFactory> factoryClass = (Class<? extends PropertiesModuleFactory>) classLoader.loadClass(factoryName); + var factoryClass = (Class<? extends PropertiesModuleFactory>) classLoader.loadClass(factoryName); PropertiesModuleFactory delegate = factoryClass.getDeclaredConstructor().newInstance(); return delegate.newModule(properties, classLoader); - } catch (ClassNotFoundException | NoSuchMethodException e) { - throw new GroovyRuntimeException("Unable to load module factory ["+factoryName+"]",e); - } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { - throw new GroovyRuntimeException("Unable to instantiate module factory ["+factoryName+"]",e); + } catch (final ClassNotFoundException | NoSuchMethodException e) { + throw new GroovyRuntimeException("Unable to load module factory [" + factoryName + "]", e); + } catch (final InstantiationException | IllegalAccessException | InvocationTargetException e) { + throw new GroovyRuntimeException("Unable to instantiate module factory [" + factoryName + "]", e); } } + return MetaInfExtensionModule.newModule(properties, classLoader); } - }
