Skip to content

Conversation

@trancexpress
Copy link
Contributor

Fixes: #2108

@trancexpress
Copy link
Contributor Author

trancexpress commented Nov 6, 2025

First error I run into:

package test;

import org.junit.jupiter.api.Test;

public class TestTest {

	@Test
	public void test() {
		System.out.println("test");
	}
}
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: TestPlugin3
Bundle-SymbolicName: TestPlugin3
Bundle-Version: 1.0.0.qualifier
Require-Bundle: org.eclipse.swt,
 org.eclipse.jface,
 org.junit,
 junit-jupiter-api
Automatic-Module-Name: TestPlugin3
Bundle-RequiredExecutionEnvironment: JavaSE-21
!ENTRY org.eclipse.ui 4 0 2025-11-06 16:09:36.024
!MESSAGE Unhandled event loop exception
!STACK 0
java.lang.NoClassDefFoundError: org/junit/platform/engine/support/hierarchical/HierarchicalTestEngine
	at java.base/java.lang.ClassLoader.defineClass1(Native Method)
	at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1027)
	at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150)
	at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:862)
	at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:760)
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:681)
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:639)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
	at org.eclipse.osgi.internal.framework.ContextFinder.loadClass(ContextFinder.java:150)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Class.java:536)
	at java.base/java.lang.Class.forName(Class.java:515)
	at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.nextProviderClass(ServiceLoader.java:1217)
	at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNextService(ServiceLoader.java:1228)
	at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNext(ServiceLoader.java:1273)
	at java.base/java.util.ServiceLoader$2.hasNext(ServiceLoader.java:1309)
	at java.base/java.util.ServiceLoader$3.hasNext(ServiceLoader.java:1393)
	at java.base/java.lang.Iterable.forEach(Iterable.java:74)
	at org.junit.platform.launcher.core.LauncherFactory.collectTestEngines(LauncherFactory.java:163)
	at org.junit.platform.launcher.core.LauncherFactory.createDefaultLauncher(LauncherFactory.java:140)
	at org.junit.platform.launcher.core.LauncherFactory.lambda$create$0(LauncherFactory.java:133)
	at org.junit.platform.launcher.core.DefaultLauncherSession.lambda$new$0(DefaultLauncherSession.java:67)
	at org.junit.platform.launcher.core.ClasspathAlignmentCheckingLauncherInterceptor.intercept(ClasspathAlignmentCheckingLauncherInterceptor.java:25)
	at org.junit.platform.launcher.core.DefaultLauncherSession.<init>(DefaultLauncherSession.java:67)
	at org.junit.platform.launcher.core.SessionPerRequestLauncher.createSession(SessionPerRequestLauncher.java:86)
	at org.junit.platform.launcher.core.SessionPerRequestLauncher.discover(SessionPerRequestLauncher.java:59)
	at org.eclipse.jdt.internal.junit6.runner.JUnit6TestReference.<init>(JUnit6TestReference.java:47)
	at org.eclipse.jdt.internal.junit6.runner.JUnit6TestLoader.createUnfilteredTest(JUnit6TestLoader.java:88)
	at org.eclipse.jdt.internal.junit6.runner.JUnit6TestLoader.createTest(JUnit6TestLoader.java:69)
	at org.eclipse.jdt.internal.junit6.runner.JUnit6TestLoader.loadTests(JUnit6TestLoader.java:56)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:504)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:748)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:443)
	at org.eclipse.pde.internal.junit.runtime.RemotePluginTestRunner.main(RemotePluginTestRunner.java:110)
	at org.eclipse.pde.internal.junit.runtime.PlatformUITestHarness.lambda$0(PlatformUITestHarness.java:45)
	at org.eclipse.e4.ui.internal.workbench.swt.E4Testable.lambda$1(E4Testable.java:127)
	at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:40)
	at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:132)
	at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:5083)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:4548)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1147)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:339)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1038)
	at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153)
	at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:677)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:339)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:583)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:173)
	at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:185)
	at org.eclipse.pde.internal.junit.runtime.NonUIThreadTestApplication.start(NonUIThreadTestApplication.java:58)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:219)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:149)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:115)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:467)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:298)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:615)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:563)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1415)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1387)
Caused by: java.lang.ClassNotFoundException: org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
	... 63 more
diff --git a/ui/org.eclipse.pde.launching/src/org/eclipse/pde/launching/JUnitLaunchConfigurationDelegate.java b/ui/org.eclipse.pde.launching/src/org/eclipse/pde/launching/JUnitLaunchConfigurationDelegate.java
index dfd2610cdf..d561adbd4b 100644
--- a/ui/org.eclipse.pde.launching/src/org/eclipse/pde/launching/JUnitLaunchConfigurationDelegate.java
+++ b/ui/org.eclipse.pde.launching/src/org/eclipse/pde/launching/JUnitLaunchConfigurationDelegate.java
@@ -518,8 +518,12 @@ public class JUnitLaunchConfigurationDelegate extends org.eclipse.jdt.junit.laun
                fAllBundles = fModels.keySet().stream().collect(Collectors.groupingBy(m -> m.getPluginBase().getId(), LinkedHashMap::new, Collectors.toCollection(ArrayList::new)));
                launchMode = launch.getLaunchMode();
 
+               System.out.println("Before");
+               fModels.keySet().stream().map(IPluginModelBase::getBundleDescription).filter(d -> d.getSymbolicName().startsWith("junit")).forEach(System.out::println);
                // implicitly add the plug-ins required for JUnit testing if necessary
                JUnitLaunchRequirements.addRequiredJunitRuntimePlugins(configuration, fAllBundles, fModels);
+               System.out.println("After");
+               fModels.keySet().stream().map(IPluginModelBase::getBundleDescription).filter(d -> d.getSymbolicName().startsWith("junit")).forEach(System.out::println);
 
                String attribute = launch.getAttribute(PDE_JUNIT_SHOW_COMMAND);
                boolean isShowCommand = false;
Before
junit-platform-suite-api_6.0.1
junit-platform-launcher_6.0.1
junit-platform-engine_6.0.1
junit-jupiter-engine_6.0.1
junit-jupiter-api_6.0.1
junit-platform-commons_6.0.1
After
junit-platform-suite-api_6.0.1
junit-platform-launcher_6.0.1
junit-platform-engine_6.0.1
junit-jupiter-engine_6.0.1
junit-jupiter-api_6.0.1
junit-platform-commons_6.0.1
junit-platform-suite-engine_6.0.1
junit-jupiter-params_6.0.1

The available bundles seem fine... Maybe something to do with the removal of MultiBundleClassLoader?

@github-actions
Copy link

github-actions bot commented Nov 6, 2025

Test Results

   774 files  + 3     774 suites  +3   58m 9s ⏱️ + 6m 30s
 3 648 tests +11   3 573 ✅  - 10   54 💤 ±0  21 ❌ +21 
10 878 runs  +33  10 652 ✅  - 30  163 💤 ±0  63 ❌ +63 

For more details on these failures, see this check.

Results for commit 8a9777c. ± Comparison against base commit b00ef59.

♻️ This comment has been updated with latest results.

@trancexpress
Copy link
Contributor Author

Next error is:

!ENTRY org.eclipse.ui 4 0 2025-11-06 18:03:17.711
!MESSAGE Unhandled event loop exception
!STACK 0
org.junit.platform.commons.PreconditionViolationException: Cannot create Launcher without at least one TestEngine; consider adding an engine implementation JAR to the classpath
	at org.junit.platform.commons.util.Preconditions.condition(Preconditions.java:339)
	at org.junit.platform.launcher.core.DefaultLauncher.<init>(DefaultLauncher.java:61)
	at org.junit.platform.launcher.core.LauncherFactory.createDefaultLauncher(LauncherFactory.java:142)
	at org.junit.platform.launcher.core.LauncherFactory.lambda$create$0(LauncherFactory.java:133)
	at org.junit.platform.launcher.core.DefaultLauncherSession.lambda$new$0(DefaultLauncherSession.java:67)
	at org.junit.platform.launcher.core.ClasspathAlignmentCheckingLauncherInterceptor.intercept(ClasspathAlignmentCheckingLauncherInterceptor.java:25)
	at org.junit.platform.launcher.core.DefaultLauncherSession.<init>(DefaultLauncherSession.java:67)
	at org.junit.platform.launcher.core.SessionPerRequestLauncher.createSession(SessionPerRequestLauncher.java:86)
	at org.junit.platform.launcher.core.SessionPerRequestLauncher.discover(SessionPerRequestLauncher.java:59)
	at org.eclipse.jdt.internal.junit6.runner.JUnit6TestReference.<init>(JUnit6TestReference.java:47)
	at org.eclipse.jdt.internal.junit6.runner.JUnit6TestLoader.createUnfilteredTest(JUnit6TestLoader.java:88)
	at org.eclipse.jdt.internal.junit6.runner.JUnit6TestLoader.createTest(JUnit6TestLoader.java:69)
	at org.eclipse.jdt.internal.junit6.runner.JUnit6TestLoader.loadTests(JUnit6TestLoader.java:56)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:504)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:748)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:443)
	at org.eclipse.pde.internal.junit.runtime.RemotePluginTestRunner.main(RemotePluginTestRunner.java:111)
	at org.eclipse.pde.internal.junit.runtime.PlatformUITestHarness.lambda$0(PlatformUITestHarness.java:45)
	at org.eclipse.e4.ui.internal.workbench.swt.E4Testable.lambda$1(E4Testable.java:127)
	at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:40)
	at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:132)
	at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:5083)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:4548)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1147)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:339)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1038)
	at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153)
	at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:677)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:339)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:583)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:173)
	at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:185)
	at org.eclipse.pde.internal.junit.runtime.NonUIThreadTestApplication.start(NonUIThreadTestApplication.java:58)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:219)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:149)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:115)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:467)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:298)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:615)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:563)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1415)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1387)

@laeubi
Copy link
Contributor

laeubi commented Nov 6, 2025

@trancexpress we have added some import restirctions on some other parts of PDE/JDT that are used here.

Beside that, I would like to first see a successful run in pure JDT (is this already possible?) and maybe one should delay PDE support to next release... it really do not bring any value right now.

@trancexpress
Copy link
Contributor Author

@trancexpress we have added some import restirctions on some other parts of PDE/JDT that are used here.

I'll check what needs to change, no problem.

Beside that, I would like to first see a successful run in pure JDT (is this already possible?)

Only with the 2 PRs linked in #2108:

The SDK build is broken, so we cannot merge either. But once we merge them, yes, plain JUnit tests run with JUnit 6.

maybe one should delay PDE support to next release... it really do not bring any value right now.

We would have to add some sort of validation on the launch, and more. Right now the launch defaults to JUnit 6, as soon as eclipse-jdt/eclipse.jdt.ui#2560 is used.

For plug-in tests we'll need to filter out the JUnit 6 option, if we are delaying PDE support by a release. How much time do we have @iloveeclipse ?

@iloveeclipse
Copy link
Member

How much time do we have

Ideally "bigger" changes should be done before M3 planned for next thursday/friday.
Smaller improvements I guess can be done for RC1 too (21 November).

@trancexpress trancexpress marked this pull request as ready for review November 6, 2025 18:34
@trancexpress
Copy link
Contributor Author

With the latest changes here, as well as eclipse-jdt/eclipse.jdt#145 and
eclipse-jdt/eclipse.jdt.ui#2560, I can run:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: TestPlugin3Junit5
Bundle-SymbolicName: TestPlugin3Junit5
Bundle-Version: 1.0.0.qualifier
Require-Bundle: org.eclipse.swt,
 org.eclipse.jface,
 org.junit,
 junit-jupiter-api;bundle-version="[5,6)",
 junit-platform-suite-api;bundle-version="[1,2)"
Automatic-Module-Name: TestPlugin3Junit5
Bundle-RequiredExecutionEnvironment: JavaSE-21
package test;

import org.junit.jupiter.api.Test;

public class TestTestJUnit5 {

	@Test
	public void test() {
		System.out.println("test");
	}
}
package test;

import org.junit.platform.suite.api.SelectClasses;
import org.junit.platform.suite.api.Suite;

@Suite
@SelectClasses({
	TestTestJUnit5.class,
})
public class TSJUnit5 {

}
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: TestPlugin3
Bundle-SymbolicName: TestPlugin3Junit6
Bundle-Version: 1.0.0.qualifier
Require-Bundle: org.eclipse.swt,
 org.eclipse.jface,
 org.junit,
 junit-jupiter-api,
 junit-platform-suite-api
Automatic-Module-Name: TestPlugin3
Bundle-RequiredExecutionEnvironment: JavaSE-21
package test;

import org.junit.jupiter.api.Test;

public class TestTestJUnit6 {

	@Test
	public void test() {
		System.out.println("test");
	}
}
package test;

import org.junit.platform.suite.api.SelectClasses;
import org.junit.platform.suite.api.Suite;

@Suite
@SelectClasses({
	TestTestJUnit6.class,
})
public class TSJUnit6 {

}

@iloveeclipse
Copy link
Member

With the latest changes here, as well as eclipse-jdt/eclipse.jdt#145 and
eclipse-jdt/eclipse.jdt.ui#2560, I can run:

With JUnit 5, correct? Because it is what manifest says.

@trancexpress
Copy link
Contributor Author

@laeubi it would be great if you can take a look. If you think we should delay JUnit 6 support until the next release, so that we get more manual testing, I think that would be fine as well. But we'll need to disable the plug-in test launch JUnit 6 choice. Unless we delay the entire JUnit 6 choice in launches.

@trancexpress
Copy link
Contributor Author

With JUnit 5, correct? Because it is what manifest says.

One set of manifest and sources with JUnit 5, the other set of manifest and sources with JUnit 6.

@trancexpress
Copy link
Contributor Author

trancexpress commented Nov 8, 2025

Seems like we don't have a build with the latest JUnit 6 changes in JDT UI. We'll have to wait more here.

I also see problems with #2113, maybe it will be best to include the new tests here. Similar to the JDT UI PR/tests.

@HannesWell
Copy link
Member

Seems like we don't have a build with the latest JUnit 6 changes in JDT UI. We'll have to wait more here.

Yes, tonight's I-build failed but I have already prepared a fix and I'm currently in the process of verifying it.
I'm also working on other unrelated changes that I'd like to have in soon, so I'll propably not kick off one I-build immediately.
Would you continue to work on this today or would tomorrows I-build be the one you use anyways?

I also see problems with #2113, maybe it will be best to include the new tests here. Similar to the JDT UI PR/tests.

I think that makes sense to have the new functionality tested immediately. This also makes it simpler to review and test this change.

@trancexpress
Copy link
Contributor Author

trancexpress commented Nov 8, 2025

Looks like JUnit 4 vintage test plug-in launches are broken with changes here.

package test;
import org.junit.Test;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith;

@RunWith(JUnitPlatform.class)
public class Test2 {

	@Test
	public void test() {

	}

}
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: TestJUnit4Vintage
Bundle-SymbolicName: TestJUnit4Vintage
Bundle-Version: 1.0.0.qualifier
Require-Bundle: org.junit;bundle-version="4.12.0",
 junit-platform-runner;bundle-version="[1.4.0,2.0.0)",
 junit-jupiter-api;bundle-version="[5.4.0,6.0.0)"
Automatic-Module-Name: TestJUnit4Vintage
Bundle-RequiredExecutionEnvironment: JavaSE-17

Among other problems I see in tests.

It might be good to look into disabling the JUnit 6 choice for plug-in test launches, in case we don't manage to fix everything that doesn't work until the end of the next week.

@trancexpress trancexpress force-pushed the gh2108 branch 2 times, most recently from 1ab5883 to 8a9777c Compare November 9, 2025 13:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support JUnit 6 plug-in test launches

4 participants