Skip to content

Validate that a JUnit 5 launch has no dependencies to JUnit 6 bundles#2101

Closed
trancexpress wants to merge 2 commits intoeclipse-pde:masterfrom
trancexpress:gh2045_test
Closed

Validate that a JUnit 5 launch has no dependencies to JUnit 6 bundles#2101
trancexpress wants to merge 2 commits intoeclipse-pde:masterfrom
trancexpress:gh2045_test

Conversation

@trancexpress
Copy link
Contributor

@trancexpress trancexpress commented Nov 5, 2025

This pull request introduces support for custom OSGi ResolverHooks in the PDE launch and validation workflow, specifically enabling exclusion of JUnit 6 bundles when running JUnit 5 tests. The changes add a mechanism to inject a ResolverHook into the bundle validation process and implement a hook that filters out JUnit 6 bundles, improving compatibility and reliability of JUnit 5 plug-in test launches.

@trancexpress
Copy link
Contributor Author

@laeubi do you mean something like this? Coming from your comment here: #2092 (comment)

Or we report errors in some way instead of removing the candidate?

We do enter the new code with this in the MANIFEST.MF:

 org.junit,
 junit-jupiter-api

But removing the JUnit 6 bundle doesn't seem to fix the launch. There is no error dialog but still no tests are executed.

@github-actions
Copy link

github-actions bot commented Nov 5, 2025

Test Results

  623 files   -   148    623 suites   - 148   51m 38s ⏱️ - 7m 58s
3 648 tests ±    0  3 593 ✅  -     1   54 💤 ± 0  1 ❌ +1 
8 213 runs   - 2 665  8 073 ✅  - 2 642  139 💤  - 24  1 ❌ +1 

For more details on these failures, see this check.

Results for commit e2ae6c4. ± Comparison against base commit df29a67.

♻️ This comment has been updated with latest results.

@trancexpress trancexpress force-pushed the gh2045_test branch 3 times, most recently from 2ad2daa to 84cefb2 Compare November 6, 2025 07:22
@trancexpress
Copy link
Contributor Author

If I don't skip junit bundles in the outer loop, the validation does detect the case where junit-jupiter-api is unrestricted in the MANIFEST.MF. But org.eclipse.e4.ui.workbench.renderers.swt.ToolBarManagerRendererTest fails to run and org.apache.ant is not mentioned in the list of bundles of the validation dialog...

@trancexpress trancexpress force-pushed the gh2045_test branch 2 times, most recently from b5694f1 to a675712 Compare November 6, 2025 12:07
@trancexpress trancexpress force-pushed the gh2045_test branch 2 times, most recently from b19fd69 to 4be4962 Compare November 6, 2025 13:33
@trancexpress trancexpress changed the title Gh2045 test Validate that a JUnit 5 launch has no dependencies to JUnit 6 bundles Nov 6, 2025
@trancexpress trancexpress force-pushed the gh2045_test branch 3 times, most recently from 6638c00 to ce96f32 Compare November 6, 2025 14:00
@trancexpress
Copy link
Contributor Author

With MANIFEST.MF:

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

The dialog is:

Screenshot_20251106_160440

With removing the optional resolution check and running ToolBarManagerRendererTest:

Screenshot_20251106_154234

@laeubi WDYT?

@laeubi
Copy link
Contributor

laeubi commented Nov 6, 2025

The text might be a bit improved but that's something that can be done later, beside that it looks good and will allow the user to identify the issue.

What do you think about

"JUnit "+majorversionofjunitbundle+" is incompatible with selected JUnit "+versionweactuallywant+" runtime selected for the launch"

I think we should just state this as is and not add "may" .. from the second picture we maybe like to record the offending resource only once, I assume the same bundle has two requirements that can cause problems.

@trancexpress
Copy link
Contributor Author

trancexpress commented Nov 6, 2025

from the second picture we maybe like to record the offending resource only once, I assume the same bundle has two requirements that can cause problems.

IMO best to list all involved bundles. There are actually several requirements, likely package imports:

Screenshot_20251106_150809

This is why I check in the code that we don't show the same message multiple times.

@trancexpress trancexpress marked this pull request as ready for review November 6, 2025 14:44
@trancexpress trancexpress force-pushed the gh2045_test branch 3 times, most recently from 5544b96 to e1584df Compare November 10, 2025 17:16
@trancexpress
Copy link
Contributor Author

We'll probably miss the release with the changes here.

@trancexpress trancexpress force-pushed the gh2045_test branch 2 times, most recently from f690a67 to 4430925 Compare November 11, 2025 07:57
@trancexpress
Copy link
Contributor Author

The Windows fail is:

Running org.eclipse.e4.tools.compatibility.migration.tests.E4MigrationToolTest
Perspective: Plug-in Development
  Info [partID=topLeft]
  Info [partID=org.eclipse.ui.internal.ViewStack@3e4f80cb, relativeID=topLeft, relationship=2, left=757, right=253, ratio=0.7495049]
  Info [partID=org.eclipse.ui.editorss, relativeID=topLeft, relationship=2, left=414, right=1438, ratio=0.22354212]
  Info [partID=bottomRight, relativeID=org.eclipse.ui.editorss, relationship=4, left=632, right=316, ratio=0.6666667]
  Info [partID=org.eclipse.ui.internal.ViewStack@4441d567, relativeID=org.eclipse.ui.editorss, relationship=2, left=568, right=190, ratio=0.74934036]
Perspective: Debug
  Info [partID=org.eclipse.debug.internal.ui.NavigatorFolderView]
  Info [partID=stickyFolderRight, relativeID=org.eclipse.debug.internal.ui.NavigatorFolderView, relationship=2, left=1391, right=464, ratio=0.74986523]
  Info [partID=org.eclipse.debug.internal.ui.ConsoleFolderView, relativeID=org.eclipse.debug.internal.ui.NavigatorFolderView, relationship=4, left=735, right=246, ratio=0.74923545]
  Info [partID=org.eclipse.ui.editorss, relativeID=org.eclipse.debug.internal.ui.NavigatorFolderView, relationship=4, left=330, right=405, ratio=0.4489796]
  Info [partID=org.eclipse.debug.internal.ui.OutlineFolderView, relativeID=org.eclipse.ui.editorss, relationship=2, left=1391, right=464, ratio=0.74986523]
  Info [partID=org.eclipse.debug.internal.ui.ToolsFolderView, relativeID=org.eclipse.debug.internal.ui.NavigatorFolderView, relationship=2, left=927, right=928, ratio=0.49973047]
Perspective: ResourceExport
  Info [partID=topLeft]
  Info [partID=stickyFolderRight, relativeID=topLeft, relationship=2, left=1873, right=625, ratio=0.74979985]
  Info [partID=bottomRight, relativeID=org.eclipse.gef.ui.palette_view, relationship=4, left=834, right=430, ratio=0.6598101]
  Info [partID=org.eclipse.ui.editorss, relativeID=org.eclipse.gef.ui.palette_view, relationship=2, left=295, right=1554, ratio=0.1595457]
  Info [partID=bottomLeft, relativeID=topLeft, relationship=4, left=632, right=632, ratio=0.5]
Error:  Timeout of 1200s exceeded. Process was killed

@trancexpress trancexpress force-pushed the gh2045_test branch 3 times, most recently from af16082 to c1a5507 Compare November 11, 2025 13:03
@trancexpress
Copy link
Contributor Author

Fail in Linux tests is:

org.eclipse.pde.ui.tests.launcher.PluginBasedLaunchTest.testGetMergedBundleMap_multipleWorkspacePluginVersions_multipleSpecificVersion -- Time elapsed: 0.351 s <<< FAILURE!
org.opentest4j.AssertionFailedError: 

expected: 
  {
  plugin.a-1.0.0(w)="default:default",
  plugin.a-2.0.0(w)="default:default"
  }
 but was: 
  {
  org.eclipse.core.contenttype-3.9.800.v20251105-1620(e)="default:default",
  org.eclipse.core.jobs-3.15.700.v20250725-1147(e)="default:default",
  org.eclipse.equinox.app-1.7.500.v20250629-0337(e)="default:default",
  org.eclipse.equinox.common-3.20.300.v20250907-1347(e)="2:true",
  org.eclipse.equinox.preferences-3.12.0.v20250721-0426(e)="default:default",
  org.eclipse.equinox.registry-3.12.600.v20250906-0651(e)="default:default",
  plugin.a-1.0.0(w)="default:default",
  plugin.a-2.0.0(w)="default:default"
  }
	at org.eclipse.pde.ui.tests.launcher.AbstractLaunchTest.assertPluginMapsEquals(AbstractLaunchTest.java:138)
	at org.eclipse.pde.ui.tests.launcher.PluginBasedLaunchTest.assertGetMergedBundleMap(PluginBasedLaunchTest.java:1095)
	at org.eclipse.pde.ui.tests.launcher.PluginBasedLaunchTest.assertGetMergedBundleMap(PluginBasedLaunchTest.java:1080)
	at org.eclipse.pde.ui.tests.launcher.PluginBasedLaunchTest.assertGetMergedBundleMap(PluginBasedLaunchTest.java:1070)
	at org.eclipse.pde.ui.tests.launcher.PluginBasedLaunchTest.testGetMergedBundleMap_multipleWorkspacePluginVersions_multipleSpecificVersion(PluginBasedLaunchTest.java:285)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at org.eclipse.pde.ui.tests.runtime.TestUtils$1.evaluate(TestUtils.java:267)
	at org.eclipse.pde.ui.tests.runtime.TestUtils$1.evaluate(TestUtils.java:267)
	at org.eclipse.pde.ui.tests.runtime.TestUtils$1.evaluate(TestUtils.java:267)

@trancexpress
Copy link
Contributor Author

I've discussed with @iloveeclipse , we'll delay this until the next release cycle. Its safer that way.

@trancexpress
Copy link
Contributor Author

On the topic of the optional package imports in org.apache.ant, we've started seeing these OSGI errors:

!ENTRY bundle1.tests 4 0 2025-11-30 19:58:22.247
!MESSAGE FrameworkEvent ERROR
!STACK 0
org.osgi.framework.BundleException: Could not resolve module: bundle1.tests [565]
  Unresolved requirement: Require-Bundle: bundle2.tests
    -> Bundle-SymbolicName: bundle2.tests; bundle-version="8.8.1"; singleton:="true"
       bundle2.tests [816]
         No resolution report for the bundle.  Bundle was not resolved because of a uses constraint violation.
  org.apache.felix.resolver.reason.ReasonException: Uses constraint violation. Unable to resolve resource bundle2.tests [osgi.identity; type="osgi.bundle"; version:Version="8.8.1"; osgi.identity="bundle2.tests"; singleton:="true"] because it is exposed to package 'org.junit.platform.launcher' from resources junit-platform-launcher [osgi.identity; type="osgi.bundle"; version:Version="1.14.1"; osgi.identity="junit-platform-launcher"] and junit-platform-launcher [osgi.identity; type="osgi.bundle"; version:Version="6.0.1"; osgi.identity="junit-platform-launcher"] via two dependency chains.

Chain 1:
  bundle2.tests [osgi.identity; type="osgi.bundle"; version:Version="8.8.1"; osgi.identity="bundle2.tests"; singleton:="true"]
    require: (&(osgi.wiring.bundle=junit-platform-launcher)(&(bundle-version>=1.14.0)(!(bundle-version>=6.0.0))))
     |
    provide: osgi.wiring.bundle: junit-platform-launcher
  junit-platform-launcher [osgi.identity; type="osgi.bundle"; version:Version="1.14.1"; osgi.identity="junit-platform-launcher"]

Chain 2:
  bundle2.tests [osgi.identity; type="osgi.bundle"; version:Version="8.8.1"; osgi.identity="bundle2.tests"; singleton:="true"]
    require: (osgi.wiring.bundle=org.apache.ant)
     |
    provide: osgi.wiring.bundle; bundle-version:Version="1.10.15.v20240901-1000"; osgi.wiring.bundle="org.apache.ant"
  org.apache.ant [osgi.identity; type="osgi.bundle"; version:Version="1.10.15.v20240901-1000"; osgi.identity="org.apache.ant"]
    import: (osgi.wiring.package=org.junit.platform.launcher)
     |
    export: osgi.wiring.package: org.junit.platform.launcher
  junit-platform-launcher [osgi.identity; type="osgi.bundle"; version:Version="6.0.1"; osgi.identity="junit-platform-launcher"]
	at org.eclipse.osgi.container.Module.start(Module.java:495)
	at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel$2.run(ModuleContainer.java:2110)
	at org.eclipse.osgi.internal.framework.EquinoxContainerAdaptor$1$1.execute(EquinoxContainerAdaptor.java:146)
	at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.incStartLevel(ModuleContainer.java:2101)
	at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.incStartLevel(ModuleContainer.java:2041)
	at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.doContainerStartLevel(ModuleContainer.java:2003)
	at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.dispatchEvent(ModuleContainer.java:1915)
	at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.dispatchEvent(ModuleContainer.java:1)
	at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
	at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:341)

We have a bundle (our central tests bundle) that depends on org.apache.ant and re-exports JUnit 5 dependencies (now version constrained).

We started seeing those errors when moving to JLS 25 / required execution JavaSE-25 of all things...

@merks
Copy link
Contributor

merks commented Dec 1, 2025

Of course ant's package requirement on org.junit.platform.launcher can only be wired to available package export of junit-platform-launcher version 6.0.1 if that's included in the launch along with the package import from junit-platform-launcher version 1.14.1.

@trancexpress
Copy link
Contributor Author

trancexpress commented Dec 1, 2025

Of course ant's package requirement on org.junit.platform.launcher can only be wired to available package export of junit-platform-launcher version 6.0.1 if that's included in the launch along with the package import from junit-platform-launcher version 1.14.1.

Unfortunately we are not seeing this all the time and in particular didn't see this when moving to 4.38 platform. And we do use ant code that itself uses JUnit jupiter code (we extend one of the ant result formatters, which itself is an execution listener).

So I'm not sure what was being used for the ant bundle so far and why it wasn't JUnit 6, as you say it should be. Even when launching tests from the Eclipse SDK, we don't see this issue. Its when we launch our test application, that itself discovers and launches our tests. Though the conflict is also sometimes reported when running the p2 application from our built platform...

Anyway, I wanted only to mention this. We are still investigating our problem; we will anyway be updating to JUnit 6.

@trancexpress
Copy link
Contributor Author

So I'm not sure what was being used for the ant bundle so far and why it wasn't JUnit 6, as you say it should be.

To update on this, it should be an artifact from how we build our test product (we put together folders on the file system and then run a p2 application). Starting the test session with -clean resolved the problems.

trancexpress and others added 2 commits December 6, 2025 11:22
This change introduces support for custom OSGi ResolverHooks in the PDE launch and validation workflow,
specifically enabling exclusion of JUnit 6 bundles when running JUnit 5 tests.
The changes add a mechanism to inject a ResolverHook into the bundle validation process
and implement a hook that filters out JUnit 6 bundles,
improving compatibility and reliability of JUnit 5 plug-in test launches.

Fixes: eclipse-pde#2045
@eclipse-pde-bot
Copy link
Contributor

This pull request changes some projects for the first time in this development cycle.
Therefore the following files need a version increment:

features/org.eclipse.pde.unittest.junit-feature/feature.xml
ui/org.eclipse.pde.launching/META-INF/MANIFEST.MF
ui/org.eclipse.pde.unittest.junit/META-INF/MANIFEST.MF

An additional commit containing all the necessary changes was pushed to the top of this PR's branch. To obtain these changes (for example if you want to push more changes) either fetch from your fork or apply the git patch.

Git patch
From 79e376cea0c0c83cd0e851a64f319b47b54cb4fd Mon Sep 17 00:00:00 2001
From: Eclipse PDE Bot <pde-bot@eclipse.org>
Date: Sat, 6 Dec 2025 09:23:44 +0000
Subject: [PATCH] Version bump(s) for 4.39 stream


diff --git a/features/org.eclipse.pde.unittest.junit-feature/feature.xml b/features/org.eclipse.pde.unittest.junit-feature/feature.xml
index 175b86fb6b..f622a481f3 100644
--- a/features/org.eclipse.pde.unittest.junit-feature/feature.xml
+++ b/features/org.eclipse.pde.unittest.junit-feature/feature.xml
@@ -2,7 +2,7 @@
 <feature
       id="org.eclipse.pde.unittest.junit"
       label="%featureName"
-      version="1.0.1200.qualifier"
+      version="1.0.1300.qualifier"
       provider-name="%providerName"
       license-feature="org.eclipse.license"
       license-feature-version="0.0.0">
diff --git a/ui/org.eclipse.pde.launching/META-INF/MANIFEST.MF b/ui/org.eclipse.pde.launching/META-INF/MANIFEST.MF
index 45e9365482..4d331f7d01 100644
--- a/ui/org.eclipse.pde.launching/META-INF/MANIFEST.MF
+++ b/ui/org.eclipse.pde.launching/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: %name
 Bundle-SymbolicName: org.eclipse.pde.launching;singleton:=true
-Bundle-Version: 3.13.600.qualifier
+Bundle-Version: 3.13.700.qualifier
 Bundle-RequiredExecutionEnvironment: JavaSE-17
 Bundle-Vendor: %provider-name
 Require-Bundle: org.eclipse.jdt.junit.core;bundle-version="[3.6.0,4.0.0)",
diff --git a/ui/org.eclipse.pde.unittest.junit/META-INF/MANIFEST.MF b/ui/org.eclipse.pde.unittest.junit/META-INF/MANIFEST.MF
index 59f7d8b1d7..a872b0d9f1 100644
--- a/ui/org.eclipse.pde.unittest.junit/META-INF/MANIFEST.MF
+++ b/ui/org.eclipse.pde.unittest.junit/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@ Automatic-Module-Name: org.eclipse.pde.unittest.junit
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.pde.unittest.junit;singleton:=true
-Bundle-Version: 1.2.200.qualifier
+Bundle-Version: 1.2.300.qualifier
 Bundle-Activator: org.eclipse.pde.unittest.junit.JUnitPluginTestPlugin
 Bundle-ActivationPolicy: lazy
 Bundle-Vendor: %providerName
-- 
2.52.0

Further information are available in Common Build Issues - Missing version increments.

@trancexpress
Copy link
Contributor Author

Fail on Mac is:

 org.eclipse.pde.ui.tests.target.TargetEnvironmentTestCase.testProjectWithJVMImports -- Time elapsed: 0.853 s <<< FAILURE!
java.lang.AssertionError: expected:<[]> but was:<[Marker [on: /foo.bar/META-INF/MANIFEST.MF, id: 0, type: org.eclipse.pde.core.problem, severity: ERROR(2), attributes: [categoryId: fatal, compilerKey: compilers.p.unresolved-import, lineNumber: 6, message: Neither an available bundle nor the associated JRE export package 'java.util.function', packageName: java.util.function, problemId: 4103], created: 12/6/25, 9:29 AM]]>
	at org.junit.Assert.fail(Assert.java:89)
	at org.junit.Assert.failNotEquals(Assert.java:835)
	at org.junit.Assert.assertEquals(Assert.java:120)
	at org.junit.Assert.assertEquals(Assert.java:146)
	at org.eclipse.pde.ui.tests.target.TargetEnvironmentTestCase.testProjectWithJVMImports(TargetEnvironmentTestCase.java:209)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at org.eclipse.pde.ui.tests.runtime.TestUtils$1.evaluate(TestUtils.java:267)
	at org.eclipse.pde.ui.tests.runtime.TestUtils$1.evaluate(TestUtils.java:267)

@trancexpress
Copy link
Contributor Author

I can't construct a bad case anymore; I do see mixed JUnit 5 and 6 dependencies (even junit-platform-engine, which was causing problems before) in JUnitLaunchConfigurationDelegate.preLaunchCheck(), after the call to JUnitLaunchRequirements.addRequiredJunitRuntimePlugins().

But the JUnit plug-in test launch works fine, both for JUnit 5 and 6.

Maybe some fixes in SPIBundleClassLoader are making this also work? Any idea @laeubi ? I'm not sure why we had problems before and now we just don't.

@trancexpress
Copy link
Contributor Author

Since I can no longer construct a case that runs into the error, closing this.

org.junit.platform.engine.TestEngine: org.junit.jupiter.engine.JupiterTestEngine not a subtype

We can always come back to this if some issue is opened with such problems.

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.

4 participants