diff --git a/base/org.codehaus.groovy30/.checkstyle b/base/org.codehaus.groovy30/.checkstyle
index 935ab0f7ad..271f102419 100644
--- a/base/org.codehaus.groovy30/.checkstyle
+++ b/base/org.codehaus.groovy30/.checkstyle
@@ -56,6 +56,7 @@
+
diff --git a/base/org.codehaus.groovy30/src/org/codehaus/groovy/runtime/m12n/MetaInfExtensionModule.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/runtime/m12n/MetaInfExtensionModule.java
new file mode 100644
index 0000000000..08c7e50e49
--- /dev/null
+++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/runtime/m12n/MetaInfExtensionModule.java
@@ -0,0 +1,99 @@
+/*
+ * 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 org.codehaus.groovy.runtime.m12n;
+
+import groovy.lang.GroovyRuntimeException;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * A {@link SimpleExtensionModule} implementation which reads extension classes
+ * metadata from META-INF.
+ *
+ * @since 2.0.0
+ */
+public class MetaInfExtensionModule extends SimpleExtensionModule {
+ /* GRECLIPSE edit
+ private static final Logger LOG = Logger.getLogger(MetaInfExtensionModule.class.getName());
+ */
+ public static final String MODULE_INSTANCE_CLASSES_KEY = "extensionClasses";
+ public static final String MODULE_STATIC_CLASSES_KEY = "staticExtensionClasses";
+
+ private final List instanceExtensionClasses;
+ private final List staticExtensionClasses;
+
+ @Override
+ public List getInstanceMethodsExtensionClasses() {
+ return instanceExtensionClasses;
+ }
+
+ @Override
+ public List getStaticMethodsExtensionClasses() {
+ return staticExtensionClasses;
+ }
+
+ private MetaInfExtensionModule(final String moduleName, final String moduleVersion, final List instanceExtensionClasses, final List staticExtensionClasses) {
+ super(moduleName, moduleVersion);
+ this.instanceExtensionClasses = instanceExtensionClasses;
+ this.staticExtensionClasses = staticExtensionClasses;
+ }
+
+ public static MetaInfExtensionModule newModule(final Properties properties, final ClassLoader loader) {
+ String name = properties.getProperty(PropertiesModuleFactory.MODULE_NAME_KEY);
+ if (name == null)
+ throw new GroovyRuntimeException("Module file hasn't set the module name using key [" + PropertiesModuleFactory.MODULE_NAME_KEY + "]");
+ String version = properties.getProperty(PropertiesModuleFactory.MODULE_VERSION_KEY);
+ if (version == null)
+ throw new GroovyRuntimeException("Module file hasn't set the module version using key [" + PropertiesModuleFactory.MODULE_VERSION_KEY + "]");
+ String[] extensionClasses = properties.getProperty(MODULE_INSTANCE_CLASSES_KEY, "").trim().split("[,; ]");
+ String[] staticExtensionClasses = properties.getProperty(MODULE_STATIC_CLASSES_KEY, "").trim().split("[,; ]");
+ List instanceClasses = new ArrayList(extensionClasses.length);
+ List staticClasses = new ArrayList(staticExtensionClasses.length);
+ List errors = new LinkedList();
+ loadExtensionClass(loader, extensionClasses, instanceClasses, errors);
+ loadExtensionClass(loader, staticExtensionClasses, staticClasses, errors);
+ if (!errors.isEmpty()) {
+ /* GRECLIPSE edit
+ for (String error : errors) {
+ LOG.warning("Module [" + name + "] - Unable to load extension class [" + error + "]");
+ }
+ */
+ org.codehaus.groovy.eclipse.GroovyLogManager.manager.log(org.codehaus.groovy.eclipse.TraceCategory.CLASSPATH,
+ "Module [" + name + "] - Unable to load extension class" + (errors.size() > 1 ? "es" : "") + " " + errors);
+ // GRECLIPSE end
+ }
+ return new MetaInfExtensionModule(name, version, instanceClasses, staticClasses);
+ }
+
+ private static void loadExtensionClass(ClassLoader loader, String[] extensionClasses, List instanceClasses, List errors) {
+ for (String extensionClass : extensionClasses) {
+ try {
+ extensionClass = extensionClass.trim();
+ if (extensionClass.length() > 0) {
+ instanceClasses.add(loader.loadClass(extensionClass));
+ }
+ } catch (ClassNotFoundException | NoClassDefFoundError | UnsupportedClassVersionError e) {
+ errors.add(extensionClass);
+ }
+ }
+ }
+}
diff --git a/base/org.codehaus.groovy40/.checkstyle b/base/org.codehaus.groovy40/.checkstyle
index a388947f69..8e6904034f 100644
--- a/base/org.codehaus.groovy40/.checkstyle
+++ b/base/org.codehaus.groovy40/.checkstyle
@@ -53,6 +53,7 @@
+
diff --git a/base/org.codehaus.groovy40/src/org/codehaus/groovy/runtime/m12n/MetaInfExtensionModule.java b/base/org.codehaus.groovy40/src/org/codehaus/groovy/runtime/m12n/MetaInfExtensionModule.java
new file mode 100644
index 0000000000..08c7e50e49
--- /dev/null
+++ b/base/org.codehaus.groovy40/src/org/codehaus/groovy/runtime/m12n/MetaInfExtensionModule.java
@@ -0,0 +1,99 @@
+/*
+ * 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 org.codehaus.groovy.runtime.m12n;
+
+import groovy.lang.GroovyRuntimeException;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * A {@link SimpleExtensionModule} implementation which reads extension classes
+ * metadata from META-INF.
+ *
+ * @since 2.0.0
+ */
+public class MetaInfExtensionModule extends SimpleExtensionModule {
+ /* GRECLIPSE edit
+ private static final Logger LOG = Logger.getLogger(MetaInfExtensionModule.class.getName());
+ */
+ public static final String MODULE_INSTANCE_CLASSES_KEY = "extensionClasses";
+ public static final String MODULE_STATIC_CLASSES_KEY = "staticExtensionClasses";
+
+ private final List instanceExtensionClasses;
+ private final List staticExtensionClasses;
+
+ @Override
+ public List getInstanceMethodsExtensionClasses() {
+ return instanceExtensionClasses;
+ }
+
+ @Override
+ public List getStaticMethodsExtensionClasses() {
+ return staticExtensionClasses;
+ }
+
+ private MetaInfExtensionModule(final String moduleName, final String moduleVersion, final List instanceExtensionClasses, final List staticExtensionClasses) {
+ super(moduleName, moduleVersion);
+ this.instanceExtensionClasses = instanceExtensionClasses;
+ this.staticExtensionClasses = staticExtensionClasses;
+ }
+
+ public static MetaInfExtensionModule newModule(final Properties properties, final ClassLoader loader) {
+ String name = properties.getProperty(PropertiesModuleFactory.MODULE_NAME_KEY);
+ if (name == null)
+ throw new GroovyRuntimeException("Module file hasn't set the module name using key [" + PropertiesModuleFactory.MODULE_NAME_KEY + "]");
+ String version = properties.getProperty(PropertiesModuleFactory.MODULE_VERSION_KEY);
+ if (version == null)
+ throw new GroovyRuntimeException("Module file hasn't set the module version using key [" + PropertiesModuleFactory.MODULE_VERSION_KEY + "]");
+ String[] extensionClasses = properties.getProperty(MODULE_INSTANCE_CLASSES_KEY, "").trim().split("[,; ]");
+ String[] staticExtensionClasses = properties.getProperty(MODULE_STATIC_CLASSES_KEY, "").trim().split("[,; ]");
+ List instanceClasses = new ArrayList(extensionClasses.length);
+ List staticClasses = new ArrayList(staticExtensionClasses.length);
+ List errors = new LinkedList();
+ loadExtensionClass(loader, extensionClasses, instanceClasses, errors);
+ loadExtensionClass(loader, staticExtensionClasses, staticClasses, errors);
+ if (!errors.isEmpty()) {
+ /* GRECLIPSE edit
+ for (String error : errors) {
+ LOG.warning("Module [" + name + "] - Unable to load extension class [" + error + "]");
+ }
+ */
+ org.codehaus.groovy.eclipse.GroovyLogManager.manager.log(org.codehaus.groovy.eclipse.TraceCategory.CLASSPATH,
+ "Module [" + name + "] - Unable to load extension class" + (errors.size() > 1 ? "es" : "") + " " + errors);
+ // GRECLIPSE end
+ }
+ return new MetaInfExtensionModule(name, version, instanceClasses, staticClasses);
+ }
+
+ private static void loadExtensionClass(ClassLoader loader, String[] extensionClasses, List instanceClasses, List errors) {
+ for (String extensionClass : extensionClasses) {
+ try {
+ extensionClass = extensionClass.trim();
+ if (extensionClass.length() > 0) {
+ instanceClasses.add(loader.loadClass(extensionClass));
+ }
+ } catch (ClassNotFoundException | NoClassDefFoundError | UnsupportedClassVersionError e) {
+ errors.add(extensionClass);
+ }
+ }
+ }
+}
diff --git a/base/org.codehaus.groovy50/.checkstyle b/base/org.codehaus.groovy50/.checkstyle
index 5b45f7b9ce..418779755b 100644
--- a/base/org.codehaus.groovy50/.checkstyle
+++ b/base/org.codehaus.groovy50/.checkstyle
@@ -48,6 +48,7 @@
+
diff --git a/base/org.codehaus.groovy50/src/org/codehaus/groovy/runtime/m12n/MetaInfExtensionModule.java b/base/org.codehaus.groovy50/src/org/codehaus/groovy/runtime/m12n/MetaInfExtensionModule.java
new file mode 100644
index 0000000000..08c7e50e49
--- /dev/null
+++ b/base/org.codehaus.groovy50/src/org/codehaus/groovy/runtime/m12n/MetaInfExtensionModule.java
@@ -0,0 +1,99 @@
+/*
+ * 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 org.codehaus.groovy.runtime.m12n;
+
+import groovy.lang.GroovyRuntimeException;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * A {@link SimpleExtensionModule} implementation which reads extension classes
+ * metadata from META-INF.
+ *
+ * @since 2.0.0
+ */
+public class MetaInfExtensionModule extends SimpleExtensionModule {
+ /* GRECLIPSE edit
+ private static final Logger LOG = Logger.getLogger(MetaInfExtensionModule.class.getName());
+ */
+ public static final String MODULE_INSTANCE_CLASSES_KEY = "extensionClasses";
+ public static final String MODULE_STATIC_CLASSES_KEY = "staticExtensionClasses";
+
+ private final List instanceExtensionClasses;
+ private final List staticExtensionClasses;
+
+ @Override
+ public List getInstanceMethodsExtensionClasses() {
+ return instanceExtensionClasses;
+ }
+
+ @Override
+ public List getStaticMethodsExtensionClasses() {
+ return staticExtensionClasses;
+ }
+
+ private MetaInfExtensionModule(final String moduleName, final String moduleVersion, final List instanceExtensionClasses, final List staticExtensionClasses) {
+ super(moduleName, moduleVersion);
+ this.instanceExtensionClasses = instanceExtensionClasses;
+ this.staticExtensionClasses = staticExtensionClasses;
+ }
+
+ public static MetaInfExtensionModule newModule(final Properties properties, final ClassLoader loader) {
+ String name = properties.getProperty(PropertiesModuleFactory.MODULE_NAME_KEY);
+ if (name == null)
+ throw new GroovyRuntimeException("Module file hasn't set the module name using key [" + PropertiesModuleFactory.MODULE_NAME_KEY + "]");
+ String version = properties.getProperty(PropertiesModuleFactory.MODULE_VERSION_KEY);
+ if (version == null)
+ throw new GroovyRuntimeException("Module file hasn't set the module version using key [" + PropertiesModuleFactory.MODULE_VERSION_KEY + "]");
+ String[] extensionClasses = properties.getProperty(MODULE_INSTANCE_CLASSES_KEY, "").trim().split("[,; ]");
+ String[] staticExtensionClasses = properties.getProperty(MODULE_STATIC_CLASSES_KEY, "").trim().split("[,; ]");
+ List instanceClasses = new ArrayList(extensionClasses.length);
+ List staticClasses = new ArrayList(staticExtensionClasses.length);
+ List errors = new LinkedList();
+ loadExtensionClass(loader, extensionClasses, instanceClasses, errors);
+ loadExtensionClass(loader, staticExtensionClasses, staticClasses, errors);
+ if (!errors.isEmpty()) {
+ /* GRECLIPSE edit
+ for (String error : errors) {
+ LOG.warning("Module [" + name + "] - Unable to load extension class [" + error + "]");
+ }
+ */
+ org.codehaus.groovy.eclipse.GroovyLogManager.manager.log(org.codehaus.groovy.eclipse.TraceCategory.CLASSPATH,
+ "Module [" + name + "] - Unable to load extension class" + (errors.size() > 1 ? "es" : "") + " " + errors);
+ // GRECLIPSE end
+ }
+ return new MetaInfExtensionModule(name, version, instanceClasses, staticClasses);
+ }
+
+ private static void loadExtensionClass(ClassLoader loader, String[] extensionClasses, List instanceClasses, List errors) {
+ for (String extensionClass : extensionClasses) {
+ try {
+ extensionClass = extensionClass.trim();
+ if (extensionClass.length() > 0) {
+ instanceClasses.add(loader.loadClass(extensionClass));
+ }
+ } catch (ClassNotFoundException | NoClassDefFoundError | UnsupportedClassVersionError e) {
+ errors.add(extensionClass);
+ }
+ }
+ }
+}
diff --git a/base/org.eclipse.jdt.groovy.core/src/org/codehaus/jdt/groovy/internal/compiler/GroovyClassLoaderFactory.java b/base/org.eclipse.jdt.groovy.core/src/org/codehaus/jdt/groovy/internal/compiler/GroovyClassLoaderFactory.java
index 834d62dc18..400fbb675f 100644
--- a/base/org.eclipse.jdt.groovy.core/src/org/codehaus/jdt/groovy/internal/compiler/GroovyClassLoaderFactory.java
+++ b/base/org.eclipse.jdt.groovy.core/src/org/codehaus/jdt/groovy/internal/compiler/GroovyClassLoaderFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2009-2023 the original author or authors.
+ * Copyright 2009-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -384,8 +384,24 @@ public Set getDefaultCategories() {
}
}, this).scanClasspathModules();
}
+
+ java.util.function.Predicate loads = (c) -> {
+ try {
+ c.getDeclaredFields();
+ return true; // primed
+ } catch (LinkageError e) {
+ if (GroovyLogManager.manager.hasLoggers()) {
+ GroovyLogManager.manager.log(TraceCategory.CLASSPATH,
+ "Failed to init " + c + " with " + this + "\n\t" + e.getMessage());
+ }
+ return false;
+ }
+ };
+
staticCategories.add(dgsm);
+ staticCategories.removeIf(loads.negate());
objectCategories.addAll(staticCategories);
+ objectCategories.removeIf(loads.negate());
defaultCategories = objectCategories;
defaultStaticCategories = staticCategories;
diff --git a/ide/org.codehaus.groovy.eclipse.dsl/src/org/codehaus/groovy/eclipse/dsl/script/DSLDScriptExecutor.java b/ide/org.codehaus.groovy.eclipse.dsl/src/org/codehaus/groovy/eclipse/dsl/script/DSLDScriptExecutor.java
index 6084309fca..e82f5f86ab 100644
--- a/ide/org.codehaus.groovy.eclipse.dsl/src/org/codehaus/groovy/eclipse/dsl/script/DSLDScriptExecutor.java
+++ b/ide/org.codehaus.groovy.eclipse.dsl/src/org/codehaus/groovy/eclipse/dsl/script/DSLDScriptExecutor.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2009-2023 the original author or authors.
+ * Copyright 2009-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -75,7 +75,7 @@ public Object executeScript(IStorage scriptFile) {
Class scriptType = null;
try {
scriptType = classLoader.parseClass(scriptText, scriptName);
- } catch (AssertionError | Exception e) {
+ } catch (AssertionError | LinkageError | Exception e) {
if (GroovyLogManager.manager.hasLoggers()) {
StringWriter writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
@@ -99,8 +99,7 @@ public Object executeScript(IStorage scriptFile) {
if (GroovyLogManager.manager.hasLoggers()) {
GroovyLogManager.manager.log(TraceCategory.DSL, e.getMessage());
}
- } catch (AssertionError | Exception e) {
- // log exception to the event console and the error log
+ } catch (AssertionError | LinkageError | Exception e) {
GroovyDSLCoreActivator.logException(e);
}
return null;