ExtensionException in OSGi environment for global extension
AndreasTu opened this issue · comments
Describe the bug
In an OSGi (e.g. Eclipse PDE) test execution spock throws an exception since change of #1995, which now tries to discover extensions from the ContextClassLoader and the Spock ClassLoader.
This now leads to the exception like:
Caused by: org.spockframework.runtime.extension.ExtensionException: Duplicated Extension declaration for [org.spockframework.runtime.extension.builtin.GlobalTimeoutExtension]
Source 1: jar:file:/<...>/spock-core-2.4-M5-groovy-4.0.jar!/META-INF/services/org.spockframework.runtime.extension.IGlobalExtension
Source 2: bundleresource://128.fwk1844173705/META-INF/services/org.spockframework.runtime.extension.IGlobalExtension
This is most likely caused by having two different version of a library on the classpath.
at org.spockframework.runtime.ExtensionClassesLoader.loadClasses(ExtensionClassesLoader.java:46)
at org.spockframework.runtime.ExtensionClassesLoader.loadExtensionClassesFromDefaultLocation(ExtensionClassesLoader.java:33)
at org.spockframework.runtime.RunContext.createBottomContext(RunContext.java:230)
at org.spockframework.runtime.RunContext.get(RunContext.java:195)
at org.spockframework.runtime.SpockEngine.discover(SpockEngine.java:21)
at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverEngineRoot(EngineDiscoveryOrchestrator.java:152)
This use due to the OSGi discrepancy of MultiBundleClassLoader returning jar:file:/
URLs, but the OSGi loader bundleresource://
URLs. See change in Eclipse PDE, which uses FileLocator.resolve()
.
We should probably change the behavior to the behavior of JUnit5 org.junit.platform.launcher.core.ServiceLoaderRegistry.load()
which does only ask the ContextClassLoader
and not the Spock ClassLoader, see org.junit.platform.commons.util.ClassLoaderUtils.getDefaultClassLoader()
.
Currently the method ReflectionUtil.getResourcesFromClassLoaders()
tries both, which lead to that issue.
So the proposal ist to change the method getResourcesFromClassLoaders()
to only use the ContextClassLoader`, if present, otherwise use the Spock class loader, and do not merge both.
To Reproduce
Try to load Spock 2.4-M5 in an Eclipse PDE/test env.
Expected behavior
Spock shall be loadable.
Actual behavior
org.spockframework.runtime.extension.ExtensionException: Duplicated Extension declaration for [org.spockframework.runtime.extension.builtin.GlobalTimeoutExtension]
Java version
openjdk version "21.0.5" 2024-10-15 LTS
OpenJDK Runtime Environment Corretto-21.0.5.11.1 (build 21.0.5+11-LTS)
OpenJDK 64-Bit Server VM Corretto-21.0.5.11.1 (build 21.0.5+11-LTS, mixed mode, sharing)
Buildtool version
Gradle 8.12
Build time: 2024-12-20 15:46:53 UTC
Revision: a3cacb207fec727859be9354c1937da2e59004c1
Kotlin: 2.0.21
Groovy: 3.0.22
Ant: Apache Ant(TM) version 1.10.15 compiled on August 25 2024
Launcher JVM: 21.0.5 (Amazon.com Inc. 21.0.5+11-LTS)
Daemon JVM: D:\dev.pes_eclipse\java\Amazon\21.0.5\win32\x86_64\jdk (no JDK specified, using current Java home)
OS: Windows 11 10.0 amd64
What operating system are you using
Windows
Dependencies
None
Additional context
No response