diff --git a/ui/org.eclipse.pde.junit.runtime/META-INF/MANIFEST.MF b/ui/org.eclipse.pde.junit.runtime/META-INF/MANIFEST.MF index 9881e7736a6..35cbed40639 100644 --- a/ui/org.eclipse.pde.junit.runtime/META-INF/MANIFEST.MF +++ b/ui/org.eclipse.pde.junit.runtime/META-INF/MANIFEST.MF @@ -12,4 +12,5 @@ Export-Package: org.eclipse.pde.internal.junit.runtime;x-internal:=true Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-ActivationPolicy: lazy Import-Package: org.eclipse.ui.testing;resolution:=optional +DynamicImport-Package: org.junit.platform.engine Automatic-Module-Name: org.eclipse.pde.junit.runtime diff --git a/ui/org.eclipse.pde.junit.runtime/src/org/eclipse/pde/internal/junit/runtime/RemotePluginTestRunner.java b/ui/org.eclipse.pde.junit.runtime/src/org/eclipse/pde/internal/junit/runtime/RemotePluginTestRunner.java index fd223765a96..ab87c59cd62 100644 --- a/ui/org.eclipse.pde.junit.runtime/src/org/eclipse/pde/internal/junit/runtime/RemotePluginTestRunner.java +++ b/ui/org.eclipse.pde.junit.runtime/src/org/eclipse/pde/internal/junit/runtime/RemotePluginTestRunner.java @@ -14,9 +14,12 @@ *******************************************************************************/ package org.eclipse.pde.internal.junit.runtime; +import static java.util.stream.Collectors.toCollection; + import java.io.IOException; import java.net.URL; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Enumeration; import java.util.List; @@ -99,19 +102,34 @@ private static ClassLoader createJUnit5PluginClassLoader(String testPluginName) private static List findTestEngineBundles() { BundleContext bundleContext = FrameworkUtil.getBundle(RemotePluginTestRunner.class).getBundleContext(); - List engineBundles = new ArrayList<>(); - for (Bundle bundle : bundleContext.getBundles()) { - try { - BundleWiring bundleWiring = bundle.adapt(BundleWiring.class); - Collection listResources = bundleWiring.listResources("META-INF/services", "org.junit.platform.engine.TestEngine", BundleWiring.LISTRESOURCES_LOCAL); //$NON-NLS-1$//$NON-NLS-2$ - if (!listResources.isEmpty()) { - engineBundles.add(bundle); - } - } catch (Exception e) { - // check the next bundle + return Arrays.stream(bundleContext.getBundles()).filter(RemotePluginTestRunner::providesCompatibleTestEngine).collect(toCollection(ArrayList::new)); + } + + /** + * Checks whether the bundle provides test engines. + * Ensures that test engines that can be loaded from the bundle + * are compatible with the TestEngine version in current scope. + * Otherwise, the JUnit platform's call to the ServiceLoader for + * retrieving available engines will fail. + * Incompatibilities can happen, e.g., in Tycho builds, where + * the org.eclipse.tycho.surefire.osgibooter bundle is found + * that may provide a different JUnit platform version than the + * one available via the Eclipse target platform. + */ + private static boolean providesCompatibleTestEngine(Bundle bundle) { + try { + BundleWiring bundleWiring = bundle.adapt(BundleWiring.class); + String testEngineClass = "org.junit.platform.engine.TestEngine"; //$NON-NLS-1$ + Collection engineProviders = bundleWiring.listResources("META-INF/services", testEngineClass, BundleWiring.LISTRESOURCES_LOCAL); //$NON-NLS-1$ + if (!engineProviders.isEmpty()) { + Class thisTestEngine = Class.forName(testEngineClass); + Class bundleTestEngine = bundle.loadClass(testEngineClass); + return thisTestEngine == bundleTestEngine; } + } catch (Exception e) { + // skip this bundle } - return engineBundles; + return false; } /**