Skip to content

P2ResolverImpl: Don't add implicit test deps to eclipse-test-plugin#5362

Merged
laeubi merged 1 commit intoeclipse-tycho:mainfrom
sratz:test-plugin-ui-hardness-deps
Oct 13, 2025
Merged

P2ResolverImpl: Don't add implicit test deps to eclipse-test-plugin#5362
laeubi merged 1 commit intoeclipse-tycho:mainfrom
sratz:test-plugin-ui-hardness-deps

Conversation

@sratz
Copy link
Copy Markdown
Member

@sratz sratz commented Sep 14, 2025

In c6edec4 /
https://bugs.eclipse.org/bugs/show_bug.cgi?id=443396 implicit dependencies were added to every 'eclipse-test-plugin' project to work around a very special situation: When building the eclipse.platform.ui repository the test harness is part of the same reactor build as well and the tests do not explicitly depend on it.

The dependency resolution was then failing because, quote [1],

  • Tycho sees that org.eclipse.ui.ide.application is part of the reactor, and hence filters all other versions of this bundle from the external target platform content.
  • The afterProjectsRead dependency resolution doesn't find a dependency between the eclipse-test-plugin module and the org.eclipse.ui.ide.application module, so it doesn't add it to the target platform for the eclipse-test-plugin module. (Adding only the "needed" reactor modules instead of all previously built modules is something which doesn't give us any benefits today, but it is a prerequisite for allowing parallel builds in the future.)
  • The resolution of the test runtime fails.

However, this had the undesired side-effect that these artificial dependencies were added to every other 'eclipse-test-plugin' project as well, which does not need it.

This caused every 'eclipse-test-plugin' to list all the UI hardness dependencies in their dependencies tree, even ending up in things like generated SBOMs, which is incorrect.

With recent improvements to Tycho, especially with #2092, the quoted issue above is not an issue anymore: Instead of filtering out shadowed units from the external target platform completely, it can now still access them if needed.

Therefore, this change reverts implicit adding of UI harness dependencies.

This results in a slight change of behavior when running tests in 'eclipse.platform.ui':

  • Before this change, the *project / reactor' version of the test harness was used when executing tests that did not themselves depend on the workbench.
  • After this change, the external target version of the test harness is used + some warnings are logged.
  • If this turns out to be a problem, Eclipse side has to adapt, e.g. by adding to target-platform-configuration in eclipse.platform.releng.aggregator/eclipse-platform-parent/pom.xml, restoring the previous Tycho behavior - but only at the place where it is actually needed.

[1] https://bugs.eclipse.org/bugs/show_bug.cgi?id=443396#c8

Fixes #5349.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Sep 14, 2025

Test Results

1 014 files  ±0  1 014 suites  ±0   5h 46m 53s ⏱️ + 1m 28s
1 300 tests +2  1 279 ✅ +1  20 💤 ±0  0 ❌ ±0  1 🔥 +1 
3 900 runs  +6  3 836 ✅ +5  63 💤 ±0  0 ❌ ±0  1 🔥 +1 

For more details on these errors, see this check.

Results for commit 52eabce. ± Comparison against base commit 0812cda.

This pull request removes 1 and adds 3 tests. Note that renamed tests count towards both.
org.eclipse.tycho.p2resolver.P2ResolverTest ‑ testEclipseTestPluginAutomaticallyDependsOnTestHarnesses
org.eclipse.tycho.p2resolver.P2ResolverTest ‑ testEclipseTestPluginTestHarnessesCanBeResolvedEvenIfHarnessIsPartOfReactorItself
org.eclipse.tycho.test.reactor.BomCreationTest ‑ verifyTestFragment
org.eclipse.tycho.test.reactor.BomCreationTest ‑ verifyTestStandAlone

♻️ This comment has been updated with latest results.

@laeubi
Copy link
Copy Markdown
Member

laeubi commented Sep 15, 2025

@sratz the org.eclipse.tycho.test.product.MetaRequirementsTest is somehow failing on other PRs as well (even though I not yet can reproduce it).

For the org.eclipse.tycho.test.surefire.BundleStartInSurefireTest seems to need some attention, after a quick look I can't find anything obvious here, but as it is using DS here it might be worth to check if SCR is actually included (e.g. the bundle is started like with the explicit case and assert that SCR is in the list of bundles). One then might add a required capability to SCR.

Then the aggregator build currently fails with

Caused by: org.osgi.framework.BundleException: Bundle org.eclipse.equinox.cm.test cannot be resolved:org.eclipse.equinox.cm.test [13]
  Unresolved requirement: Import-Package: org.eclipse.core.runtime

if this is expected, I would recommend to adjust the aggregator build first so we can see here it will run fine.

The individual bundles build seem to have a crash now when launching the test-runtime (usually it means it can't start up), this also needs to be investigated (and maybe fixes).

The SWT build already suceeds, so it seems to be not that bad at all, but of course if we need changes in the platform builds we possibly should document what/what and decide it is something that could affect others and maybe needs to be mentioned in a migration guide.

@sratz
Copy link
Copy Markdown
Member Author

sratz commented Sep 15, 2025

For the org.eclipse.tycho.test.surefire.BundleStartInSurefireTest seems to need some attention, after a quick look I can't find anything obvious here, but as it is using DS here it might be worth to check if SCR is actually included (e.g. the bundle is started like with the explicit case and assert that SCR is in the list of bundles). One then might add a required capability to SCR.

I think we are now seeing the side-effects: By always including the UI test harness org.eclipse.ui.ide.application in P2ResolverImpl, it went unnoticed that the actual list of dependencies in

https://github.com/sratz/tycho/blob/60cf2b997a1525d1e47bff778064b4fa87128585/tycho-surefire/tycho-surefire-plugin/src/main/java/org/eclipse/tycho/surefire/AbstractEclipseTestMojo.java#L898-L902

has become outdated.

I think we need to include org.apache.felix.scr there.

Then the aggregator build currently fails with

Caused by: org.osgi.framework.BundleException: Bundle org.eclipse.equinox.cm.test cannot be resolved:org.eclipse.equinox.cm.test [13]
  Unresolved requirement: Import-Package: org.eclipse.core.runtime

This is a bit strange, I'll investigate locally.

The individual bundles build seem to have a crash now when launching the test-runtime (usually it means it can't start up), this also needs to be investigated (and maybe fixes).

Hopefully this is fixed when we include org.apache.felix.scr.

If this doesn't help, I'll provide a PR to platform aggregator to add a<extraRequirements> to restore the previous Tycho behavior.

@laeubi
Copy link
Copy Markdown
Member

laeubi commented Sep 15, 2025

I don't think SCR is required always just often so if it is an issue why it was included before?
Also I don't think Tycho should do anything here specifically but one would need to declare specific requirements in the bundles that need it.

I think we need to include org.apache.felix.scr there.

There is not only felix but it could be any implementation!

@sratz
Copy link
Copy Markdown
Member Author

sratz commented Sep 15, 2025

I don't think SCR is required always just often so if it is an issue why it was included before? Also I don't think Tycho should do anything here specifically but one would need to declare specific requirements in the bundles that need it.

I think we need to include org.apache.felix.scr there.

There is not only felix but it could be any implementation!

By always including the full-blown UI test harness here

requirementsConsumer.accept(optionalGreedyRequirementTo("org.eclipse.ui.ide.application"));

SCR was included implicitly.

To keep things as compatible as possible I guess we should also make sure that declarative services work always?

@laeubi
Copy link
Copy Markdown
Member

laeubi commented Sep 15, 2025

To keep things as compatible as possible I guess we should also make sure that declarative services work always?

While this looks valid at the first place I think we should not do that (for the same reason we should maybe not enforce org.eclipse.ui.ide.application

If you look here it says:

A bundle that contains service components should require the osgi.extender capability from SCR. This requirement will wire the bundle to the SCR implementation and ensure that SCR is using the same org.osgi.service.component package as the bundle if the bundle uses that package.

Require-Capability: osgi.extender;
  filter:="(&(osgi.extender=osgi.component)(version>=[1.4](https://docs.osgi.org/specification/osgi.cmpn/7.0.0/service.component.html#org.osgi.service.component))(!(version>=2.0)))"

so this is also important for the runtime, and if no such thing exits it has to be possible (as it is maybe a deliberate choice of the bundle writer to make DS optional, even though not very useful).

So I think its fair enough to expect users to provide proper Manifest headers or otherwise fail. It might be different for Tycho 5, but I doubt we can make it backward compatible anyways as literally anything (including org.eclipse.ui.ide.application) could be implicitly expected by the test.

@sratz
Copy link
Copy Markdown
Member Author

sratz commented Sep 15, 2025

OK, agreed, then let's not add it implicitly.

As expected, the test failure in eclipse.platform is due to SCR missing:

Stack
org.osgi.framework.BundleException: Exception in org.eclipse.core.resources.ResourcesPlugin.start() of bundle org.eclipse.core.resources.
	at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:847)
	at org.eclipse.osgi.internal.framework.BundleContextImpl.start(BundleContextImpl.java:768)
	at org.eclipse.osgi.internal.framework.EquinoxBundle.startWorker0(EquinoxBundle.java:1066)
	at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.startWorker(EquinoxBundle.java:394)
	at org.eclipse.osgi.container.Module.doStart(Module.java:643)
	at org.eclipse.osgi.container.Module.start(Module.java:500)
	at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:528)
	at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:122)
	at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:622)
	at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:353)
	at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:417)
	at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:41)
	at org.eclipse.osgi.internal.loader.BundleLoader.findClass0(BundleLoader.java:521)
	at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:438)
	at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:195)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
	at java.base/java.lang.Class.getDeclaredMethods0(Native Method)
	at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3578)
	at java.base/java.lang.Class.getDeclaredMethods(Class.java:2676)
	at org.junit.platform.commons.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:1809)
	at org.junit.platform.commons.util.ReflectionUtils.findMethod(ReflectionUtils.java:1649)
	at org.junit.platform.commons.util.ReflectionUtils.isMethodPresent(ReflectionUtils.java:1500)
	at org.junit.jupiter.engine.discovery.predicates.TestClassPredicates.hasTestOrTestFactoryOrTestTemplateMethods(TestClassPredicates.java:106)
	at org.junit.jupiter.engine.discovery.predicates.TestClassPredicates.looksLikeIntendedTestClass(TestClassPredicates.java:81)
	at org.junit.jupiter.engine.discovery.predicates.TestClassPredicates.looksLikeIntendedTestClass(TestClassPredicates.java:75)
	at org.junit.jupiter.engine.discovery.ClassSelectorResolver.isAcceptedStandaloneTestClass(ClassSelectorResolver.java:115)
	at org.junit.jupiter.engine.discovery.ClassSelectorResolver.resolveStandaloneTestClass(ClassSelectorResolver.java:106)
	at org.junit.jupiter.engine.discovery.ClassSelectorResolver.resolve(ClassSelectorResolver.java:102)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.lambda$resolve$2(EngineDiscoveryRequestResolution.java:135)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1685)
	at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:129)
	at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:647)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolve(EngineDiscoveryRequestResolution.java:189)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolve(EngineDiscoveryRequestResolution.java:126)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolveCompletely(EngineDiscoveryRequestResolution.java:92)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.run(EngineDiscoveryRequestResolution.java:83)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolver.resolve(EngineDiscoveryRequestResolver.java:148)
	at org.junit.jupiter.engine.discovery.DiscoverySelectorResolver.resolveSelectors(DiscoverySelectorResolver.java:63)
	at org.junit.jupiter.engine.JupiterTestEngine.discover(JupiterTestEngine.java:70)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverEngineRoot(EngineDiscoveryOrchestrator.java:195)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverSafely(EngineDiscoveryOrchestrator.java:174)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discover(EngineDiscoveryOrchestrator.java:119)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discover(EngineDiscoveryOrchestrator.java:84)
	at org.junit.platform.launcher.core.DefaultLauncher.discover(DefaultLauncher.java:104)
	at org.junit.platform.launcher.core.DefaultLauncher.discover(DefaultLauncher.java:83)
	at org.junit.platform.launcher.core.DelegatingLauncher.discover(DelegatingLauncher.java:42)
	at org.junit.platform.launcher.core.InterceptingLauncher.lambda$discover$0(InterceptingLauncher.java:33)
	at org.junit.platform.launcher.core.ClasspathAlignmentCheckingLauncherInterceptor.intercept(ClasspathAlignmentCheckingLauncherInterceptor.java:25)
	at org.junit.platform.launcher.core.InterceptingLauncher.discover(InterceptingLauncher.java:33)
	at org.junit.platform.launcher.core.DelegatingLauncher.discover(DelegatingLauncher.java:42)
	at org.apache.maven.surefire.junitplatform.LazyLauncher.discover(LazyLauncher.java:50)
	at org.apache.maven.surefire.junitplatform.TestPlanScannerFilter.accept(TestPlanScannerFilter.java:52)
	at org.apache.maven.surefire.api.util.DefaultScanResult.applyFilter(DefaultScanResult.java:87)
	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.scanClasspath(JUnitPlatformProvider.java:144)
	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:124)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at org.apache.maven.surefire.api.util.ReflectionUtils.invokeMethodWithArray2(ReflectionUtils.java:137)
	at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:148)
	at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:88)
	at org.eclipse.tycho.surefire.osgibooter.OsgiSurefireBooter.invokeSureFire(OsgiSurefireBooter.java:195)
	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.tycho.surefire.osgibooter.OsgiSurefireBooter.run(OsgiSurefireBooter.java:116)
	at org.eclipse.tycho.surefire.osgibooter.HeadlessTestApplication.start(HeadlessTestApplication.java:29)
	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:627)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:575)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1431)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1403)
Caused by: java.lang.NullPointerException: Cannot invoke "org.eclipse.core.runtime.content.IContentTypeManager.addContentTypeChangeListener(org.eclipse.core.runtime.content.IContentTypeManager$IContentTypeChangeListener)" because the return value of "org.eclipse.core.runtime.Platform.getContentTypeManager()" is null
	at org.eclipse.core.internal.resources.CharsetDeltaJob.startup(CharsetDeltaJob.java:266)
	at org.eclipse.core.internal.resources.CharsetManager.startup(CharsetManager.java:590)
	at org.eclipse.core.internal.resources.Workspace.startup(Workspace.java:2681)
	at org.eclipse.core.internal.resources.Workspace.open(Workspace.java:2369)
	at org.eclipse.core.resources.ResourcesPlugin$WorkspaceInitCustomizer.addingService(ResourcesPlugin.java:591)
	at org.eclipse.core.resources.ResourcesPlugin$WorkspaceInitCustomizer.addingService(ResourcesPlugin.java:1)
	at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:947)
	at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:1)
	at org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:257)
	at org.osgi.util.tracker.AbstractTracked.trackInitial(AbstractTracked.java:184)
	at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:324)
	at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:267)
	at org.eclipse.core.resources.ResourcesPlugin.start(ResourcesPlugin.java:565)
	at org.eclipse.osgi.internal.framework.BundleContextImpl$2.run(BundleContextImpl.java:826)
	at org.eclipse.osgi.internal.framework.BundleContextImpl$2.run(BundleContextImpl.java:1)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:571)
	at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:818)
	... 81 more
Root exception:
java.lang.NullPointerException: Cannot invoke "org.eclipse.core.runtime.content.IContentTypeManager.addContentTypeChangeListener(org.eclipse.core.runtime.content.IContentTypeManager$IContentTypeChangeListener)" because the return value of "org.eclipse.core.runtime.Platform.getContentTypeManager()" is null
	at org.eclipse.core.internal.resources.CharsetDeltaJob.startup(CharsetDeltaJob.java:266)
	at org.eclipse.core.internal.resources.CharsetManager.startup(CharsetManager.java:590)
	at org.eclipse.core.internal.resources.Workspace.startup(Workspace.java:2681)
	at org.eclipse.core.internal.resources.Workspace.open(Workspace.java:2369)
	at org.eclipse.core.resources.ResourcesPlugin$WorkspaceInitCustomizer.addingService(ResourcesPlugin.java:591)
	at org.eclipse.core.resources.ResourcesPlugin$WorkspaceInitCustomizer.addingService(ResourcesPlugin.java:1)
	at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:947)
	at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:1)
	at org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:257)
	at org.osgi.util.tracker.AbstractTracked.trackInitial(AbstractTracked.java:184)
	at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:324)
	at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:267)
	at org.eclipse.core.resources.ResourcesPlugin.start(ResourcesPlugin.java:565)
	at org.eclipse.osgi.internal.framework.BundleContextImpl$2.run(BundleContextImpl.java:826)
	at org.eclipse.osgi.internal.framework.BundleContextImpl$2.run(BundleContextImpl.java:1)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:571)
	at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:818)
	at org.eclipse.osgi.internal.framework.BundleContextImpl.start(BundleContextImpl.java:768)
	at org.eclipse.osgi.internal.framework.EquinoxBundle.startWorker0(EquinoxBundle.java:1066)
	at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.startWorker(EquinoxBundle.java:394)
	at org.eclipse.osgi.container.Module.doStart(Module.java:643)
	at org.eclipse.osgi.container.Module.start(Module.java:500)
	at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:528)
	at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:122)
	at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:622)
	at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:353)
	at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:417)
	at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:41)
	at org.eclipse.osgi.internal.loader.BundleLoader.findClass0(BundleLoader.java:521)
	at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:438)
	at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:195)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
	at java.base/java.lang.Class.getDeclaredMethods0(Native Method)
	at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3578)
	at java.base/java.lang.Class.getDeclaredMethods(Class.java:2676)
	at org.junit.platform.commons.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:1809)
	at org.junit.platform.commons.util.ReflectionUtils.findMethod(ReflectionUtils.java:1649)
	at org.junit.platform.commons.util.ReflectionUtils.isMethodPresent(ReflectionUtils.java:1500)
	at org.junit.jupiter.engine.discovery.predicates.TestClassPredicates.hasTestOrTestFactoryOrTestTemplateMethods(TestClassPredicates.java:106)
	at org.junit.jupiter.engine.discovery.predicates.TestClassPredicates.looksLikeIntendedTestClass(TestClassPredicates.java:81)
	at org.junit.jupiter.engine.discovery.predicates.TestClassPredicates.looksLikeIntendedTestClass(TestClassPredicates.java:75)
	at org.junit.jupiter.engine.discovery.ClassSelectorResolver.isAcceptedStandaloneTestClass(ClassSelectorResolver.java:115)
	at org.junit.jupiter.engine.discovery.ClassSelectorResolver.resolveStandaloneTestClass(ClassSelectorResolver.java:106)
	at org.junit.jupiter.engine.discovery.ClassSelectorResolver.resolve(ClassSelectorResolver.java:102)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.lambda$resolve$2(EngineDiscoveryRequestResolution.java:135)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1685)
	at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:129)
	at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:647)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolve(EngineDiscoveryRequestResolution.java:189)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolve(EngineDiscoveryRequestResolution.java:126)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolveCompletely(EngineDiscoveryRequestResolution.java:92)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.run(EngineDiscoveryRequestResolution.java:83)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolver.resolve(EngineDiscoveryRequestResolver.java:148)
	at org.junit.jupiter.engine.discovery.DiscoverySelectorResolver.resolveSelectors(DiscoverySelectorResolver.java:63)
	at org.junit.jupiter.engine.JupiterTestEngine.discover(JupiterTestEngine.java:70)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverEngineRoot(EngineDiscoveryOrchestrator.java:195)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverSafely(EngineDiscoveryOrchestrator.java:174)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discover(EngineDiscoveryOrchestrator.java:119)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discover(EngineDiscoveryOrchestrator.java:84)
	at org.junit.platform.launcher.core.DefaultLauncher.discover(DefaultLauncher.java:104)
	at org.junit.platform.launcher.core.DefaultLauncher.discover(DefaultLauncher.java:83)
	at org.junit.platform.launcher.core.DelegatingLauncher.discover(DelegatingLauncher.java:42)
	at org.junit.platform.launcher.core.InterceptingLauncher.lambda$discover$0(InterceptingLauncher.java:33)
	at org.junit.platform.launcher.core.ClasspathAlignmentCheckingLauncherInterceptor.intercept(ClasspathAlignmentCheckingLauncherInterceptor.java:25)
	at org.junit.platform.launcher.core.InterceptingLauncher.discover(InterceptingLauncher.java:33)
	at org.junit.platform.launcher.core.DelegatingLauncher.discover(DelegatingLauncher.java:42)
	at org.apache.maven.surefire.junitplatform.LazyLauncher.discover(LazyLauncher.java:50)
	at org.apache.maven.surefire.junitplatform.TestPlanScannerFilter.accept(TestPlanScannerFilter.java:52)
	at org.apache.maven.surefire.api.util.DefaultScanResult.applyFilter(DefaultScanResult.java:87)
	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.scanClasspath(JUnitPlatformProvider.java:144)
	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:124)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at org.apache.maven.surefire.api.util.ReflectionUtils.invokeMethodWithArray2(ReflectionUtils.java:137)
	at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:148)
	at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:88)
	at org.eclipse.tycho.surefire.osgibooter.OsgiSurefireBooter.invokeSureFire(OsgiSurefireBooter.java:195)
	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.tycho.surefire.osgibooter.OsgiSurefireBooter.run(OsgiSurefireBooter.java:116)
	at org.eclipse.tycho.surefire.osgibooter.HeadlessTestApplication.start(HeadlessTestApplication.java:29)
	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:627)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:575)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1431)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1403)

I am not an expert on DS. Does this mean

  1. This particular test in eclipse.platform/resources/tests/org.eclipse.core.tests.resources.saveparticipant needs to specify an <extraRequirement>?
  2. Since org.eclipe.core.runtime apparently uses declarative services to get the IContentTypeManager, does that mean it should specify a Require-Capability: osgi.extender;?

@laeubi
Copy link
Copy Markdown
Member

laeubi commented Sep 15, 2025

If org.eclipe.core.runtime would specify Require-Capability: osgi.extender; it should be enough. Only if the test uses own DS components it also needs that header.

@sratz
Copy link
Copy Markdown
Member Author

sratz commented Sep 15, 2025

If org.eclipe.core.runtime would specify Require-Capability: osgi.extender; it should be enough. Only if the test uses own DS components it also needs that header.

I think actually org.eclipse.core.contenttype should do so, as it declares the service, but I think adding the extender requirement to the manifest was forgotten.

@laeubi
Copy link
Copy Markdown
Member

laeubi commented Sep 15, 2025

I think adding the extender requirement to the manifest was forgotten.

That's often the case sadly. Tycho try to add such things during the build, but it requires to be enabled (not 100% sure for platform build) and it means the project should use the DS annotations already (what is not always the case).

I'd like to improve that with

but it currently lacks free time (or funding) from my side so maybe not happen tomorrow ... until then we can only identify such issues and fix them manually.

@akurtakov
Copy link
Copy Markdown
Member

FWIW, swt tests are executed using plain maven surefire https://github.com/eclipse-platform/eclipse.platform.swt/blob/508ad4a15bb54e280b1727db2f4dd5bd3fc4ba17/tests/org.eclipse.swt.tests/pom.xml#L35 - we really want them to run outside of OSGi to ensure it's usable as a standalone library.

sratz added a commit to sratz/eclipse.platform that referenced this pull request Sep 15, 2025
org.eclipse.core.contenttype declares a service component, so it should
also declare the requirement to the service extender.

Otherwise, this can lead to exceptions such as the one below, in case no
extender is added.

This also adjusts org.eclipse.core.tests.harness accordingly, which
builds a custom OSGI config.ini in CustomSessionConfigurationImpl and
must now also include a SCR bundle (and its dependencies). We use
org.apache.felix.scr here.

This serves also as a preparation for
eclipse-tycho/tycho#5362

org.osgi.framework.BundleException: Exception in org.eclipse.core.resources.ResourcesPlugin.start() of bundle org.eclipse.core.resources.
	at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:847)
	at org.eclipse.osgi.internal.framework.BundleContextImpl.start(BundleContextImpl.java:768)
	at org.eclipse.osgi.internal.framework.EquinoxBundle.startWorker0(EquinoxBundle.java:1066)
	at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.startWorker(EquinoxBundle.java:394)
	at org.eclipse.osgi.container.Module.doStart(Module.java:643)
	at org.eclipse.osgi.container.Module.start(Module.java:500)
	at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:528)
	at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:122)
	at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:622)
	at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:353)
	at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:417)
	at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:41)
	at org.eclipse.osgi.internal.loader.BundleLoader.findClass0(BundleLoader.java:521)
	at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:438)
	at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:195)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
	at java.base/java.lang.Class.getDeclaredMethods0(Native Method)
	at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3578)
	at java.base/java.lang.Class.getDeclaredMethods(Class.java:2676)
	at org.junit.platform.commons.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:1809)
	at org.junit.platform.commons.util.ReflectionUtils.findMethod(ReflectionUtils.java:1649)
	at org.junit.platform.commons.util.ReflectionUtils.isMethodPresent(ReflectionUtils.java:1500)
	at org.junit.jupiter.engine.discovery.predicates.TestClassPredicates.hasTestOrTestFactoryOrTestTemplateMethods(TestClassPredicates.java:106)
	at org.junit.jupiter.engine.discovery.predicates.TestClassPredicates.looksLikeIntendedTestClass(TestClassPredicates.java:81)
	at org.junit.jupiter.engine.discovery.predicates.TestClassPredicates.looksLikeIntendedTestClass(TestClassPredicates.java:75)
	at org.junit.jupiter.engine.discovery.ClassSelectorResolver.isAcceptedStandaloneTestClass(ClassSelectorResolver.java:115)
	at org.junit.jupiter.engine.discovery.ClassSelectorResolver.resolveStandaloneTestClass(ClassSelectorResolver.java:106)
	at org.junit.jupiter.engine.discovery.ClassSelectorResolver.resolve(ClassSelectorResolver.java:102)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.lambda$resolve$2(EngineDiscoveryRequestResolution.java:135)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1685)
	at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:129)
	at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:647)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolve(EngineDiscoveryRequestResolution.java:189)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolve(EngineDiscoveryRequestResolution.java:126)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolveCompletely(EngineDiscoveryRequestResolution.java:92)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.run(EngineDiscoveryRequestResolution.java:83)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolver.resolve(EngineDiscoveryRequestResolver.java:148)
	at org.junit.jupiter.engine.discovery.DiscoverySelectorResolver.resolveSelectors(DiscoverySelectorResolver.java:63)
	at org.junit.jupiter.engine.JupiterTestEngine.discover(JupiterTestEngine.java:70)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverEngineRoot(EngineDiscoveryOrchestrator.java:195)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverSafely(EngineDiscoveryOrchestrator.java:174)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discover(EngineDiscoveryOrchestrator.java:119)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discover(EngineDiscoveryOrchestrator.java:84)
	at org.junit.platform.launcher.core.DefaultLauncher.discover(DefaultLauncher.java:104)
	at org.junit.platform.launcher.core.DefaultLauncher.discover(DefaultLauncher.java:83)
	at org.junit.platform.launcher.core.DelegatingLauncher.discover(DelegatingLauncher.java:42)
	at org.junit.platform.launcher.core.InterceptingLauncher.lambda$discover$0(InterceptingLauncher.java:33)
	at org.junit.platform.launcher.core.ClasspathAlignmentCheckingLauncherInterceptor.intercept(ClasspathAlignmentCheckingLauncherInterceptor.java:25)
	at org.junit.platform.launcher.core.InterceptingLauncher.discover(InterceptingLauncher.java:33)
	at org.junit.platform.launcher.core.DelegatingLauncher.discover(DelegatingLauncher.java:42)
	at org.apache.maven.surefire.junitplatform.LazyLauncher.discover(LazyLauncher.java:50)
	at org.apache.maven.surefire.junitplatform.TestPlanScannerFilter.accept(TestPlanScannerFilter.java:52)
	at org.apache.maven.surefire.api.util.DefaultScanResult.applyFilter(DefaultScanResult.java:87)
	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.scanClasspath(JUnitPlatformProvider.java:144)
	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:124)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at org.apache.maven.surefire.api.util.ReflectionUtils.invokeMethodWithArray2(ReflectionUtils.java:137)
	at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:148)
	at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:88)
	at org.eclipse.tycho.surefire.osgibooter.OsgiSurefireBooter.invokeSureFire(OsgiSurefireBooter.java:195)
	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.tycho.surefire.osgibooter.OsgiSurefireBooter.run(OsgiSurefireBooter.java:116)
	at org.eclipse.tycho.surefire.osgibooter.HeadlessTestApplication.start(HeadlessTestApplication.java:29)
	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:627)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:575)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1431)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1403)
Caused by: java.lang.NullPointerException: Cannot invoke "org.eclipse.core.runtime.content.IContentTypeManager.addContentTypeChangeListener(org.eclipse.core.runtime.content.IContentTypeManager$IContentTypeChangeListener)" because the return value of "org.eclipse.core.runtime.Platform.getContentTypeManager()" is null
	at org.eclipse.core.internal.resources.CharsetDeltaJob.startup(CharsetDeltaJob.java:266)
	at org.eclipse.core.internal.resources.CharsetManager.startup(CharsetManager.java:590)
	at org.eclipse.core.internal.resources.Workspace.startup(Workspace.java:2681)
	at org.eclipse.core.internal.resources.Workspace.open(Workspace.java:2369)
	at org.eclipse.core.resources.ResourcesPlugin$WorkspaceInitCustomizer.addingService(ResourcesPlugin.java:591)
	at org.eclipse.core.resources.ResourcesPlugin$WorkspaceInitCustomizer.addingService(ResourcesPlugin.java:1)
	at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:947)
	at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:1)
	at org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:257)
	at org.osgi.util.tracker.AbstractTracked.trackInitial(AbstractTracked.java:184)
	at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:324)
	at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:267)
	at org.eclipse.core.resources.ResourcesPlugin.start(ResourcesPlugin.java:565)
	at org.eclipse.osgi.internal.framework.BundleContextImpl$2.run(BundleContextImpl.java:826)
	at org.eclipse.osgi.internal.framework.BundleContextImpl$2.run(BundleContextImpl.java:1)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:571)
	at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:818)
	... 81 more
Root exception:
java.lang.NullPointerException: Cannot invoke "org.eclipse.core.runtime.content.IContentTypeManager.addContentTypeChangeListener(org.eclipse.core.runtime.content.IContentTypeManager$IContentTypeChangeListener)" because the return value of "org.eclipse.core.runtime.Platform.getContentTypeManager()" is null
	at org.eclipse.core.internal.resources.CharsetDeltaJob.startup(CharsetDeltaJob.java:266)
	at org.eclipse.core.internal.resources.CharsetManager.startup(CharsetManager.java:590)
	at org.eclipse.core.internal.resources.Workspace.startup(Workspace.java:2681)
	at org.eclipse.core.internal.resources.Workspace.open(Workspace.java:2369)
	at org.eclipse.core.resources.ResourcesPlugin$WorkspaceInitCustomizer.addingService(ResourcesPlugin.java:591)
	at org.eclipse.core.resources.ResourcesPlugin$WorkspaceInitCustomizer.addingService(ResourcesPlugin.java:1)
	at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:947)
	at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:1)
	at org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:257)
	at org.osgi.util.tracker.AbstractTracked.trackInitial(AbstractTracked.java:184)
	at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:324)
	at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:267)
	at org.eclipse.core.resources.ResourcesPlugin.start(ResourcesPlugin.java:565)
	at org.eclipse.osgi.internal.framework.BundleContextImpl$2.run(BundleContextImpl.java:826)
	at org.eclipse.osgi.internal.framework.BundleContextImpl$2.run(BundleContextImpl.java:1)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:571)
	at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:818)
	at org.eclipse.osgi.internal.framework.BundleContextImpl.start(BundleContextImpl.java:768)
	at org.eclipse.osgi.internal.framework.EquinoxBundle.startWorker0(EquinoxBundle.java:1066)
	at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.startWorker(EquinoxBundle.java:394)
	at org.eclipse.osgi.container.Module.doStart(Module.java:643)
	at org.eclipse.osgi.container.Module.start(Module.java:500)
	at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:528)
	at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:122)
	at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:622)
	at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:353)
	at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:417)
	at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:41)
	at org.eclipse.osgi.internal.loader.BundleLoader.findClass0(BundleLoader.java:521)
	at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:438)
	at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:195)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
	at java.base/java.lang.Class.getDeclaredMethods0(Native Method)
	at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3578)
	at java.base/java.lang.Class.getDeclaredMethods(Class.java:2676)
	at org.junit.platform.commons.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:1809)
	at org.junit.platform.commons.util.ReflectionUtils.findMethod(ReflectionUtils.java:1649)
	at org.junit.platform.commons.util.ReflectionUtils.isMethodPresent(ReflectionUtils.java:1500)
	at org.junit.jupiter.engine.discovery.predicates.TestClassPredicates.hasTestOrTestFactoryOrTestTemplateMethods(TestClassPredicates.java:106)
	at org.junit.jupiter.engine.discovery.predicates.TestClassPredicates.looksLikeIntendedTestClass(TestClassPredicates.java:81)
	at org.junit.jupiter.engine.discovery.predicates.TestClassPredicates.looksLikeIntendedTestClass(TestClassPredicates.java:75)
	at org.junit.jupiter.engine.discovery.ClassSelectorResolver.isAcceptedStandaloneTestClass(ClassSelectorResolver.java:115)
	at org.junit.jupiter.engine.discovery.ClassSelectorResolver.resolveStandaloneTestClass(ClassSelectorResolver.java:106)
	at org.junit.jupiter.engine.discovery.ClassSelectorResolver.resolve(ClassSelectorResolver.java:102)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.lambda$resolve$2(EngineDiscoveryRequestResolution.java:135)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1685)
	at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:129)
	at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:647)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolve(EngineDiscoveryRequestResolution.java:189)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolve(EngineDiscoveryRequestResolution.java:126)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolveCompletely(EngineDiscoveryRequestResolution.java:92)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.run(EngineDiscoveryRequestResolution.java:83)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolver.resolve(EngineDiscoveryRequestResolver.java:148)
	at org.junit.jupiter.engine.discovery.DiscoverySelectorResolver.resolveSelectors(DiscoverySelectorResolver.java:63)
	at org.junit.jupiter.engine.JupiterTestEngine.discover(JupiterTestEngine.java:70)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverEngineRoot(EngineDiscoveryOrchestrator.java:195)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverSafely(EngineDiscoveryOrchestrator.java:174)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discover(EngineDiscoveryOrchestrator.java:119)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discover(EngineDiscoveryOrchestrator.java:84)
	at org.junit.platform.launcher.core.DefaultLauncher.discover(DefaultLauncher.java:104)
	at org.junit.platform.launcher.core.DefaultLauncher.discover(DefaultLauncher.java:83)
	at org.junit.platform.launcher.core.DelegatingLauncher.discover(DelegatingLauncher.java:42)
	at org.junit.platform.launcher.core.InterceptingLauncher.lambda$discover$0(InterceptingLauncher.java:33)
	at org.junit.platform.launcher.core.ClasspathAlignmentCheckingLauncherInterceptor.intercept(ClasspathAlignmentCheckingLauncherInterceptor.java:25)
	at org.junit.platform.launcher.core.InterceptingLauncher.discover(InterceptingLauncher.java:33)
	at org.junit.platform.launcher.core.DelegatingLauncher.discover(DelegatingLauncher.java:42)
	at org.apache.maven.surefire.junitplatform.LazyLauncher.discover(LazyLauncher.java:50)
	at org.apache.maven.surefire.junitplatform.TestPlanScannerFilter.accept(TestPlanScannerFilter.java:52)
	at org.apache.maven.surefire.api.util.DefaultScanResult.applyFilter(DefaultScanResult.java:87)
	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.scanClasspath(JUnitPlatformProvider.java:144)
	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:124)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at org.apache.maven.surefire.api.util.ReflectionUtils.invokeMethodWithArray2(ReflectionUtils.java:137)
	at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:148)
	at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:88)
	at org.eclipse.tycho.surefire.osgibooter.OsgiSurefireBooter.invokeSureFire(OsgiSurefireBooter.java:195)
	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.tycho.surefire.osgibooter.OsgiSurefireBooter.run(OsgiSurefireBooter.java:116)
	at org.eclipse.tycho.surefire.osgibooter.HeadlessTestApplication.start(HeadlessTestApplication.java:29)
	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:627)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:575)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1431)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1403)
sratz added a commit to sratz/eclipse.platform that referenced this pull request Sep 15, 2025
* PreferencesServiceTest is not deterministic but its behavior changes
  depending on the presence of downstream plug-in
  org.eclipse.core.resources. Take this into account.

* IResourceTest should not depend on downstream plug-in
  org.eclipse.ui.ide (even inside a downstream repository).
  Use a different (upstream) filter provider in the unit test instead.

These downstream plug-ins are currently only visible because Tycho adds
the full-blown UI test harness to the target platform unconditionally,
even if there is no such actual dependency [1]. This is a cleanup in
preparation for [2].

[1] eclipse-tycho/tycho#5349
[2] eclipse-tycho/tycho#5362
laeubi pushed a commit to eclipse-platform/eclipse.platform that referenced this pull request Sep 16, 2025
org.eclipse.core.contenttype declares a service component, so it should
also declare the requirement to the service extender.

Otherwise, this can lead to exceptions such as the one below, in case no
extender is added.

This also adjusts org.eclipse.core.tests.harness accordingly, which
builds a custom OSGI config.ini in CustomSessionConfigurationImpl and
must now also include a SCR bundle (and its dependencies). We use
org.apache.felix.scr here.

This serves also as a preparation for
eclipse-tycho/tycho#5362

org.osgi.framework.BundleException: Exception in org.eclipse.core.resources.ResourcesPlugin.start() of bundle org.eclipse.core.resources.
	at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:847)
	at org.eclipse.osgi.internal.framework.BundleContextImpl.start(BundleContextImpl.java:768)
	at org.eclipse.osgi.internal.framework.EquinoxBundle.startWorker0(EquinoxBundle.java:1066)
	at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.startWorker(EquinoxBundle.java:394)
	at org.eclipse.osgi.container.Module.doStart(Module.java:643)
	at org.eclipse.osgi.container.Module.start(Module.java:500)
	at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:528)
	at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:122)
	at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:622)
	at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:353)
	at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:417)
	at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:41)
	at org.eclipse.osgi.internal.loader.BundleLoader.findClass0(BundleLoader.java:521)
	at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:438)
	at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:195)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
	at java.base/java.lang.Class.getDeclaredMethods0(Native Method)
	at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3578)
	at java.base/java.lang.Class.getDeclaredMethods(Class.java:2676)
	at org.junit.platform.commons.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:1809)
	at org.junit.platform.commons.util.ReflectionUtils.findMethod(ReflectionUtils.java:1649)
	at org.junit.platform.commons.util.ReflectionUtils.isMethodPresent(ReflectionUtils.java:1500)
	at org.junit.jupiter.engine.discovery.predicates.TestClassPredicates.hasTestOrTestFactoryOrTestTemplateMethods(TestClassPredicates.java:106)
	at org.junit.jupiter.engine.discovery.predicates.TestClassPredicates.looksLikeIntendedTestClass(TestClassPredicates.java:81)
	at org.junit.jupiter.engine.discovery.predicates.TestClassPredicates.looksLikeIntendedTestClass(TestClassPredicates.java:75)
	at org.junit.jupiter.engine.discovery.ClassSelectorResolver.isAcceptedStandaloneTestClass(ClassSelectorResolver.java:115)
	at org.junit.jupiter.engine.discovery.ClassSelectorResolver.resolveStandaloneTestClass(ClassSelectorResolver.java:106)
	at org.junit.jupiter.engine.discovery.ClassSelectorResolver.resolve(ClassSelectorResolver.java:102)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.lambda$resolve$2(EngineDiscoveryRequestResolution.java:135)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1685)
	at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:129)
	at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:647)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolve(EngineDiscoveryRequestResolution.java:189)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolve(EngineDiscoveryRequestResolution.java:126)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolveCompletely(EngineDiscoveryRequestResolution.java:92)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.run(EngineDiscoveryRequestResolution.java:83)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolver.resolve(EngineDiscoveryRequestResolver.java:148)
	at org.junit.jupiter.engine.discovery.DiscoverySelectorResolver.resolveSelectors(DiscoverySelectorResolver.java:63)
	at org.junit.jupiter.engine.JupiterTestEngine.discover(JupiterTestEngine.java:70)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverEngineRoot(EngineDiscoveryOrchestrator.java:195)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverSafely(EngineDiscoveryOrchestrator.java:174)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discover(EngineDiscoveryOrchestrator.java:119)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discover(EngineDiscoveryOrchestrator.java:84)
	at org.junit.platform.launcher.core.DefaultLauncher.discover(DefaultLauncher.java:104)
	at org.junit.platform.launcher.core.DefaultLauncher.discover(DefaultLauncher.java:83)
	at org.junit.platform.launcher.core.DelegatingLauncher.discover(DelegatingLauncher.java:42)
	at org.junit.platform.launcher.core.InterceptingLauncher.lambda$discover$0(InterceptingLauncher.java:33)
	at org.junit.platform.launcher.core.ClasspathAlignmentCheckingLauncherInterceptor.intercept(ClasspathAlignmentCheckingLauncherInterceptor.java:25)
	at org.junit.platform.launcher.core.InterceptingLauncher.discover(InterceptingLauncher.java:33)
	at org.junit.platform.launcher.core.DelegatingLauncher.discover(DelegatingLauncher.java:42)
	at org.apache.maven.surefire.junitplatform.LazyLauncher.discover(LazyLauncher.java:50)
	at org.apache.maven.surefire.junitplatform.TestPlanScannerFilter.accept(TestPlanScannerFilter.java:52)
	at org.apache.maven.surefire.api.util.DefaultScanResult.applyFilter(DefaultScanResult.java:87)
	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.scanClasspath(JUnitPlatformProvider.java:144)
	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:124)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at org.apache.maven.surefire.api.util.ReflectionUtils.invokeMethodWithArray2(ReflectionUtils.java:137)
	at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:148)
	at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:88)
	at org.eclipse.tycho.surefire.osgibooter.OsgiSurefireBooter.invokeSureFire(OsgiSurefireBooter.java:195)
	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.tycho.surefire.osgibooter.OsgiSurefireBooter.run(OsgiSurefireBooter.java:116)
	at org.eclipse.tycho.surefire.osgibooter.HeadlessTestApplication.start(HeadlessTestApplication.java:29)
	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:627)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:575)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1431)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1403)
Caused by: java.lang.NullPointerException: Cannot invoke "org.eclipse.core.runtime.content.IContentTypeManager.addContentTypeChangeListener(org.eclipse.core.runtime.content.IContentTypeManager$IContentTypeChangeListener)" because the return value of "org.eclipse.core.runtime.Platform.getContentTypeManager()" is null
	at org.eclipse.core.internal.resources.CharsetDeltaJob.startup(CharsetDeltaJob.java:266)
	at org.eclipse.core.internal.resources.CharsetManager.startup(CharsetManager.java:590)
	at org.eclipse.core.internal.resources.Workspace.startup(Workspace.java:2681)
	at org.eclipse.core.internal.resources.Workspace.open(Workspace.java:2369)
	at org.eclipse.core.resources.ResourcesPlugin$WorkspaceInitCustomizer.addingService(ResourcesPlugin.java:591)
	at org.eclipse.core.resources.ResourcesPlugin$WorkspaceInitCustomizer.addingService(ResourcesPlugin.java:1)
	at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:947)
	at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:1)
	at org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:257)
	at org.osgi.util.tracker.AbstractTracked.trackInitial(AbstractTracked.java:184)
	at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:324)
	at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:267)
	at org.eclipse.core.resources.ResourcesPlugin.start(ResourcesPlugin.java:565)
	at org.eclipse.osgi.internal.framework.BundleContextImpl$2.run(BundleContextImpl.java:826)
	at org.eclipse.osgi.internal.framework.BundleContextImpl$2.run(BundleContextImpl.java:1)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:571)
	at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:818)
	... 81 more
Root exception:
java.lang.NullPointerException: Cannot invoke "org.eclipse.core.runtime.content.IContentTypeManager.addContentTypeChangeListener(org.eclipse.core.runtime.content.IContentTypeManager$IContentTypeChangeListener)" because the return value of "org.eclipse.core.runtime.Platform.getContentTypeManager()" is null
	at org.eclipse.core.internal.resources.CharsetDeltaJob.startup(CharsetDeltaJob.java:266)
	at org.eclipse.core.internal.resources.CharsetManager.startup(CharsetManager.java:590)
	at org.eclipse.core.internal.resources.Workspace.startup(Workspace.java:2681)
	at org.eclipse.core.internal.resources.Workspace.open(Workspace.java:2369)
	at org.eclipse.core.resources.ResourcesPlugin$WorkspaceInitCustomizer.addingService(ResourcesPlugin.java:591)
	at org.eclipse.core.resources.ResourcesPlugin$WorkspaceInitCustomizer.addingService(ResourcesPlugin.java:1)
	at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:947)
	at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:1)
	at org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:257)
	at org.osgi.util.tracker.AbstractTracked.trackInitial(AbstractTracked.java:184)
	at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:324)
	at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:267)
	at org.eclipse.core.resources.ResourcesPlugin.start(ResourcesPlugin.java:565)
	at org.eclipse.osgi.internal.framework.BundleContextImpl$2.run(BundleContextImpl.java:826)
	at org.eclipse.osgi.internal.framework.BundleContextImpl$2.run(BundleContextImpl.java:1)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:571)
	at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:818)
	at org.eclipse.osgi.internal.framework.BundleContextImpl.start(BundleContextImpl.java:768)
	at org.eclipse.osgi.internal.framework.EquinoxBundle.startWorker0(EquinoxBundle.java:1066)
	at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.startWorker(EquinoxBundle.java:394)
	at org.eclipse.osgi.container.Module.doStart(Module.java:643)
	at org.eclipse.osgi.container.Module.start(Module.java:500)
	at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:528)
	at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:122)
	at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:622)
	at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:353)
	at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:417)
	at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:41)
	at org.eclipse.osgi.internal.loader.BundleLoader.findClass0(BundleLoader.java:521)
	at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:438)
	at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:195)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
	at java.base/java.lang.Class.getDeclaredMethods0(Native Method)
	at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3578)
	at java.base/java.lang.Class.getDeclaredMethods(Class.java:2676)
	at org.junit.platform.commons.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:1809)
	at org.junit.platform.commons.util.ReflectionUtils.findMethod(ReflectionUtils.java:1649)
	at org.junit.platform.commons.util.ReflectionUtils.isMethodPresent(ReflectionUtils.java:1500)
	at org.junit.jupiter.engine.discovery.predicates.TestClassPredicates.hasTestOrTestFactoryOrTestTemplateMethods(TestClassPredicates.java:106)
	at org.junit.jupiter.engine.discovery.predicates.TestClassPredicates.looksLikeIntendedTestClass(TestClassPredicates.java:81)
	at org.junit.jupiter.engine.discovery.predicates.TestClassPredicates.looksLikeIntendedTestClass(TestClassPredicates.java:75)
	at org.junit.jupiter.engine.discovery.ClassSelectorResolver.isAcceptedStandaloneTestClass(ClassSelectorResolver.java:115)
	at org.junit.jupiter.engine.discovery.ClassSelectorResolver.resolveStandaloneTestClass(ClassSelectorResolver.java:106)
	at org.junit.jupiter.engine.discovery.ClassSelectorResolver.resolve(ClassSelectorResolver.java:102)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.lambda$resolve$2(EngineDiscoveryRequestResolution.java:135)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1685)
	at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:129)
	at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:647)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolve(EngineDiscoveryRequestResolution.java:189)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolve(EngineDiscoveryRequestResolution.java:126)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolveCompletely(EngineDiscoveryRequestResolution.java:92)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.run(EngineDiscoveryRequestResolution.java:83)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolver.resolve(EngineDiscoveryRequestResolver.java:148)
	at org.junit.jupiter.engine.discovery.DiscoverySelectorResolver.resolveSelectors(DiscoverySelectorResolver.java:63)
	at org.junit.jupiter.engine.JupiterTestEngine.discover(JupiterTestEngine.java:70)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverEngineRoot(EngineDiscoveryOrchestrator.java:195)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverSafely(EngineDiscoveryOrchestrator.java:174)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discover(EngineDiscoveryOrchestrator.java:119)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discover(EngineDiscoveryOrchestrator.java:84)
	at org.junit.platform.launcher.core.DefaultLauncher.discover(DefaultLauncher.java:104)
	at org.junit.platform.launcher.core.DefaultLauncher.discover(DefaultLauncher.java:83)
	at org.junit.platform.launcher.core.DelegatingLauncher.discover(DelegatingLauncher.java:42)
	at org.junit.platform.launcher.core.InterceptingLauncher.lambda$discover$0(InterceptingLauncher.java:33)
	at org.junit.platform.launcher.core.ClasspathAlignmentCheckingLauncherInterceptor.intercept(ClasspathAlignmentCheckingLauncherInterceptor.java:25)
	at org.junit.platform.launcher.core.InterceptingLauncher.discover(InterceptingLauncher.java:33)
	at org.junit.platform.launcher.core.DelegatingLauncher.discover(DelegatingLauncher.java:42)
	at org.apache.maven.surefire.junitplatform.LazyLauncher.discover(LazyLauncher.java:50)
	at org.apache.maven.surefire.junitplatform.TestPlanScannerFilter.accept(TestPlanScannerFilter.java:52)
	at org.apache.maven.surefire.api.util.DefaultScanResult.applyFilter(DefaultScanResult.java:87)
	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.scanClasspath(JUnitPlatformProvider.java:144)
	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:124)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at org.apache.maven.surefire.api.util.ReflectionUtils.invokeMethodWithArray2(ReflectionUtils.java:137)
	at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:148)
	at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:88)
	at org.eclipse.tycho.surefire.osgibooter.OsgiSurefireBooter.invokeSureFire(OsgiSurefireBooter.java:195)
	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.tycho.surefire.osgibooter.OsgiSurefireBooter.run(OsgiSurefireBooter.java:116)
	at org.eclipse.tycho.surefire.osgibooter.HeadlessTestApplication.start(HeadlessTestApplication.java:29)
	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:627)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:575)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1431)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1403)
laeubi pushed a commit to eclipse-platform/eclipse.platform that referenced this pull request Sep 16, 2025
* PreferencesServiceTest is not deterministic but its behavior changes
  depending on the presence of downstream plug-in
  org.eclipse.core.resources. Take this into account.

* IResourceTest should not depend on downstream plug-in
  org.eclipse.ui.ide (even inside a downstream repository).
  Use a different (upstream) filter provider in the unit test instead.

These downstream plug-ins are currently only visible because Tycho adds
the full-blown UI test harness to the target platform unconditionally,
even if there is no such actual dependency [1]. This is a cleanup in
preparation for [2].

[1] eclipse-tycho/tycho#5349
[2] eclipse-tycho/tycho#5362
@sratz
Copy link
Copy Markdown
Member Author

sratz commented Sep 16, 2025

the aggregator build currently fails with

Caused by: org.osgi.framework.BundleException: Bundle org.eclipse.equinox.cm.test cannot be resolved:org.eclipse.equinox.cm.test [13]
  Unresolved requirement: Import-Package: org.eclipse.core.runtime

The root cause is because org.eclipse.core.runtime is a split package between bundles org.eclipse.core.runtime and org.eclipse.equinox.common. And with the smaller target platform now, org.eclipse.core.runtime bundle is not added implicitly anymore.

If I set -Dtycho.target.eager=true it works.

I guess the best solution would be to replace

Import-Package: org.eclipse.core.runtime

with

Require-Bundle:
  org.eclipse.equinox.common,
  org.eclipse.core.runtime

to work around this. WDYT?

@laeubi
Copy link
Copy Markdown
Member

laeubi commented Sep 16, 2025

I guess the best solution would be to replace

Yes!

@sratz
Copy link
Copy Markdown
Member Author

sratz commented Sep 16, 2025

Even better yet would be if equinox would not depend on eclipse.platform at all to avoid this kind of chicken-and-egg problem

Philipp0205 pushed a commit to Philipp0205/eclipse.platform that referenced this pull request Sep 16, 2025
org.eclipse.core.contenttype declares a service component, so it should
also declare the requirement to the service extender.

Otherwise, this can lead to exceptions such as the one below, in case no
extender is added.

This also adjusts org.eclipse.core.tests.harness accordingly, which
builds a custom OSGI config.ini in CustomSessionConfigurationImpl and
must now also include a SCR bundle (and its dependencies). We use
org.apache.felix.scr here.

This serves also as a preparation for
eclipse-tycho/tycho#5362

org.osgi.framework.BundleException: Exception in org.eclipse.core.resources.ResourcesPlugin.start() of bundle org.eclipse.core.resources.
	at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:847)
	at org.eclipse.osgi.internal.framework.BundleContextImpl.start(BundleContextImpl.java:768)
	at org.eclipse.osgi.internal.framework.EquinoxBundle.startWorker0(EquinoxBundle.java:1066)
	at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.startWorker(EquinoxBundle.java:394)
	at org.eclipse.osgi.container.Module.doStart(Module.java:643)
	at org.eclipse.osgi.container.Module.start(Module.java:500)
	at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:528)
	at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:122)
	at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:622)
	at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:353)
	at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:417)
	at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:41)
	at org.eclipse.osgi.internal.loader.BundleLoader.findClass0(BundleLoader.java:521)
	at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:438)
	at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:195)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
	at java.base/java.lang.Class.getDeclaredMethods0(Native Method)
	at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3578)
	at java.base/java.lang.Class.getDeclaredMethods(Class.java:2676)
	at org.junit.platform.commons.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:1809)
	at org.junit.platform.commons.util.ReflectionUtils.findMethod(ReflectionUtils.java:1649)
	at org.junit.platform.commons.util.ReflectionUtils.isMethodPresent(ReflectionUtils.java:1500)
	at org.junit.jupiter.engine.discovery.predicates.TestClassPredicates.hasTestOrTestFactoryOrTestTemplateMethods(TestClassPredicates.java:106)
	at org.junit.jupiter.engine.discovery.predicates.TestClassPredicates.looksLikeIntendedTestClass(TestClassPredicates.java:81)
	at org.junit.jupiter.engine.discovery.predicates.TestClassPredicates.looksLikeIntendedTestClass(TestClassPredicates.java:75)
	at org.junit.jupiter.engine.discovery.ClassSelectorResolver.isAcceptedStandaloneTestClass(ClassSelectorResolver.java:115)
	at org.junit.jupiter.engine.discovery.ClassSelectorResolver.resolveStandaloneTestClass(ClassSelectorResolver.java:106)
	at org.junit.jupiter.engine.discovery.ClassSelectorResolver.resolve(ClassSelectorResolver.java:102)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.lambda$resolve$2(EngineDiscoveryRequestResolution.java:135)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1685)
	at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:129)
	at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:647)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolve(EngineDiscoveryRequestResolution.java:189)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolve(EngineDiscoveryRequestResolution.java:126)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolveCompletely(EngineDiscoveryRequestResolution.java:92)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.run(EngineDiscoveryRequestResolution.java:83)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolver.resolve(EngineDiscoveryRequestResolver.java:148)
	at org.junit.jupiter.engine.discovery.DiscoverySelectorResolver.resolveSelectors(DiscoverySelectorResolver.java:63)
	at org.junit.jupiter.engine.JupiterTestEngine.discover(JupiterTestEngine.java:70)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverEngineRoot(EngineDiscoveryOrchestrator.java:195)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverSafely(EngineDiscoveryOrchestrator.java:174)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discover(EngineDiscoveryOrchestrator.java:119)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discover(EngineDiscoveryOrchestrator.java:84)
	at org.junit.platform.launcher.core.DefaultLauncher.discover(DefaultLauncher.java:104)
	at org.junit.platform.launcher.core.DefaultLauncher.discover(DefaultLauncher.java:83)
	at org.junit.platform.launcher.core.DelegatingLauncher.discover(DelegatingLauncher.java:42)
	at org.junit.platform.launcher.core.InterceptingLauncher.lambda$discover$0(InterceptingLauncher.java:33)
	at org.junit.platform.launcher.core.ClasspathAlignmentCheckingLauncherInterceptor.intercept(ClasspathAlignmentCheckingLauncherInterceptor.java:25)
	at org.junit.platform.launcher.core.InterceptingLauncher.discover(InterceptingLauncher.java:33)
	at org.junit.platform.launcher.core.DelegatingLauncher.discover(DelegatingLauncher.java:42)
	at org.apache.maven.surefire.junitplatform.LazyLauncher.discover(LazyLauncher.java:50)
	at org.apache.maven.surefire.junitplatform.TestPlanScannerFilter.accept(TestPlanScannerFilter.java:52)
	at org.apache.maven.surefire.api.util.DefaultScanResult.applyFilter(DefaultScanResult.java:87)
	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.scanClasspath(JUnitPlatformProvider.java:144)
	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:124)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at org.apache.maven.surefire.api.util.ReflectionUtils.invokeMethodWithArray2(ReflectionUtils.java:137)
	at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:148)
	at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:88)
	at org.eclipse.tycho.surefire.osgibooter.OsgiSurefireBooter.invokeSureFire(OsgiSurefireBooter.java:195)
	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.tycho.surefire.osgibooter.OsgiSurefireBooter.run(OsgiSurefireBooter.java:116)
	at org.eclipse.tycho.surefire.osgibooter.HeadlessTestApplication.start(HeadlessTestApplication.java:29)
	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:627)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:575)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1431)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1403)
Caused by: java.lang.NullPointerException: Cannot invoke "org.eclipse.core.runtime.content.IContentTypeManager.addContentTypeChangeListener(org.eclipse.core.runtime.content.IContentTypeManager$IContentTypeChangeListener)" because the return value of "org.eclipse.core.runtime.Platform.getContentTypeManager()" is null
	at org.eclipse.core.internal.resources.CharsetDeltaJob.startup(CharsetDeltaJob.java:266)
	at org.eclipse.core.internal.resources.CharsetManager.startup(CharsetManager.java:590)
	at org.eclipse.core.internal.resources.Workspace.startup(Workspace.java:2681)
	at org.eclipse.core.internal.resources.Workspace.open(Workspace.java:2369)
	at org.eclipse.core.resources.ResourcesPlugin$WorkspaceInitCustomizer.addingService(ResourcesPlugin.java:591)
	at org.eclipse.core.resources.ResourcesPlugin$WorkspaceInitCustomizer.addingService(ResourcesPlugin.java:1)
	at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:947)
	at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:1)
	at org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:257)
	at org.osgi.util.tracker.AbstractTracked.trackInitial(AbstractTracked.java:184)
	at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:324)
	at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:267)
	at org.eclipse.core.resources.ResourcesPlugin.start(ResourcesPlugin.java:565)
	at org.eclipse.osgi.internal.framework.BundleContextImpl$2.run(BundleContextImpl.java:826)
	at org.eclipse.osgi.internal.framework.BundleContextImpl$2.run(BundleContextImpl.java:1)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:571)
	at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:818)
	... 81 more
Root exception:
java.lang.NullPointerException: Cannot invoke "org.eclipse.core.runtime.content.IContentTypeManager.addContentTypeChangeListener(org.eclipse.core.runtime.content.IContentTypeManager$IContentTypeChangeListener)" because the return value of "org.eclipse.core.runtime.Platform.getContentTypeManager()" is null
	at org.eclipse.core.internal.resources.CharsetDeltaJob.startup(CharsetDeltaJob.java:266)
	at org.eclipse.core.internal.resources.CharsetManager.startup(CharsetManager.java:590)
	at org.eclipse.core.internal.resources.Workspace.startup(Workspace.java:2681)
	at org.eclipse.core.internal.resources.Workspace.open(Workspace.java:2369)
	at org.eclipse.core.resources.ResourcesPlugin$WorkspaceInitCustomizer.addingService(ResourcesPlugin.java:591)
	at org.eclipse.core.resources.ResourcesPlugin$WorkspaceInitCustomizer.addingService(ResourcesPlugin.java:1)
	at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:947)
	at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:1)
	at org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:257)
	at org.osgi.util.tracker.AbstractTracked.trackInitial(AbstractTracked.java:184)
	at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:324)
	at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:267)
	at org.eclipse.core.resources.ResourcesPlugin.start(ResourcesPlugin.java:565)
	at org.eclipse.osgi.internal.framework.BundleContextImpl$2.run(BundleContextImpl.java:826)
	at org.eclipse.osgi.internal.framework.BundleContextImpl$2.run(BundleContextImpl.java:1)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:571)
	at org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:818)
	at org.eclipse.osgi.internal.framework.BundleContextImpl.start(BundleContextImpl.java:768)
	at org.eclipse.osgi.internal.framework.EquinoxBundle.startWorker0(EquinoxBundle.java:1066)
	at org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.startWorker(EquinoxBundle.java:394)
	at org.eclipse.osgi.container.Module.doStart(Module.java:643)
	at org.eclipse.osgi.container.Module.start(Module.java:500)
	at org.eclipse.osgi.framework.util.SecureAction.start(SecureAction.java:528)
	at org.eclipse.osgi.internal.hooks.EclipseLazyStarter.postFindLocalClass(EclipseLazyStarter.java:122)
	at org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findLocalClass(ClasspathManager.java:622)
	at org.eclipse.osgi.internal.loader.ModuleClassLoader.findLocalClass(ModuleClassLoader.java:353)
	at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:417)
	at org.eclipse.osgi.internal.loader.sources.SingleSourcePackage.loadClass(SingleSourcePackage.java:41)
	at org.eclipse.osgi.internal.loader.BundleLoader.findClass0(BundleLoader.java:521)
	at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:438)
	at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:195)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
	at java.base/java.lang.Class.getDeclaredMethods0(Native Method)
	at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3578)
	at java.base/java.lang.Class.getDeclaredMethods(Class.java:2676)
	at org.junit.platform.commons.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:1809)
	at org.junit.platform.commons.util.ReflectionUtils.findMethod(ReflectionUtils.java:1649)
	at org.junit.platform.commons.util.ReflectionUtils.isMethodPresent(ReflectionUtils.java:1500)
	at org.junit.jupiter.engine.discovery.predicates.TestClassPredicates.hasTestOrTestFactoryOrTestTemplateMethods(TestClassPredicates.java:106)
	at org.junit.jupiter.engine.discovery.predicates.TestClassPredicates.looksLikeIntendedTestClass(TestClassPredicates.java:81)
	at org.junit.jupiter.engine.discovery.predicates.TestClassPredicates.looksLikeIntendedTestClass(TestClassPredicates.java:75)
	at org.junit.jupiter.engine.discovery.ClassSelectorResolver.isAcceptedStandaloneTestClass(ClassSelectorResolver.java:115)
	at org.junit.jupiter.engine.discovery.ClassSelectorResolver.resolveStandaloneTestClass(ClassSelectorResolver.java:106)
	at org.junit.jupiter.engine.discovery.ClassSelectorResolver.resolve(ClassSelectorResolver.java:102)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.lambda$resolve$2(EngineDiscoveryRequestResolution.java:135)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1685)
	at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:129)
	at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:647)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolve(EngineDiscoveryRequestResolution.java:189)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolve(EngineDiscoveryRequestResolution.java:126)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolveCompletely(EngineDiscoveryRequestResolution.java:92)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.run(EngineDiscoveryRequestResolution.java:83)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolver.resolve(EngineDiscoveryRequestResolver.java:148)
	at org.junit.jupiter.engine.discovery.DiscoverySelectorResolver.resolveSelectors(DiscoverySelectorResolver.java:63)
	at org.junit.jupiter.engine.JupiterTestEngine.discover(JupiterTestEngine.java:70)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverEngineRoot(EngineDiscoveryOrchestrator.java:195)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverSafely(EngineDiscoveryOrchestrator.java:174)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discover(EngineDiscoveryOrchestrator.java:119)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discover(EngineDiscoveryOrchestrator.java:84)
	at org.junit.platform.launcher.core.DefaultLauncher.discover(DefaultLauncher.java:104)
	at org.junit.platform.launcher.core.DefaultLauncher.discover(DefaultLauncher.java:83)
	at org.junit.platform.launcher.core.DelegatingLauncher.discover(DelegatingLauncher.java:42)
	at org.junit.platform.launcher.core.InterceptingLauncher.lambda$discover$0(InterceptingLauncher.java:33)
	at org.junit.platform.launcher.core.ClasspathAlignmentCheckingLauncherInterceptor.intercept(ClasspathAlignmentCheckingLauncherInterceptor.java:25)
	at org.junit.platform.launcher.core.InterceptingLauncher.discover(InterceptingLauncher.java:33)
	at org.junit.platform.launcher.core.DelegatingLauncher.discover(DelegatingLauncher.java:42)
	at org.apache.maven.surefire.junitplatform.LazyLauncher.discover(LazyLauncher.java:50)
	at org.apache.maven.surefire.junitplatform.TestPlanScannerFilter.accept(TestPlanScannerFilter.java:52)
	at org.apache.maven.surefire.api.util.DefaultScanResult.applyFilter(DefaultScanResult.java:87)
	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.scanClasspath(JUnitPlatformProvider.java:144)
	at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:124)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at org.apache.maven.surefire.api.util.ReflectionUtils.invokeMethodWithArray2(ReflectionUtils.java:137)
	at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:148)
	at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:88)
	at org.eclipse.tycho.surefire.osgibooter.OsgiSurefireBooter.invokeSureFire(OsgiSurefireBooter.java:195)
	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.tycho.surefire.osgibooter.OsgiSurefireBooter.run(OsgiSurefireBooter.java:116)
	at org.eclipse.tycho.surefire.osgibooter.HeadlessTestApplication.start(HeadlessTestApplication.java:29)
	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:627)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:575)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1431)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1403)
Philipp0205 pushed a commit to Philipp0205/eclipse.platform that referenced this pull request Sep 16, 2025
* PreferencesServiceTest is not deterministic but its behavior changes
  depending on the presence of downstream plug-in
  org.eclipse.core.resources. Take this into account.

* IResourceTest should not depend on downstream plug-in
  org.eclipse.ui.ide (even inside a downstream repository).
  Use a different (upstream) filter provider in the unit test instead.

These downstream plug-ins are currently only visible because Tycho adds
the full-blown UI test harness to the target platform unconditionally,
even if there is no such actual dependency [1]. This is a cleanup in
preparation for [2].

[1] eclipse-tycho/tycho#5349
[2] eclipse-tycho/tycho#5362
sratz added a commit to sratz/equinox that referenced this pull request Sep 16, 2025
org.eclipse.core.runtime is split across
  equinox/org.eclipse.equinox.common
and
  eclipse.platform/org.eclipse.core.runtime

which can lead to dependency resolution errors.

Replace Import-Packge with Require-Bundle to make sure
eclipse.platform/org.eclipse.core.runtime
is actually included.

See also eclipse-tycho/tycho#5362 which will
make this problem visible as it reduces the implicit target platform
content.
laeubi pushed a commit to eclipse-equinox/equinox that referenced this pull request Sep 16, 2025
org.eclipse.core.runtime is split across
  equinox/org.eclipse.equinox.common
and
  eclipse.platform/org.eclipse.core.runtime

which can lead to dependency resolution errors.

Replace Import-Packge with Require-Bundle to make sure
eclipse.platform/org.eclipse.core.runtime
is actually included.

See also eclipse-tycho/tycho#5362 which will
make this problem visible as it reduces the implicit target platform
content.
@sratz sratz force-pushed the test-plugin-ui-hardness-deps branch 2 times, most recently from dcb9c8f to 7fa6c2b Compare September 17, 2025 08:08
@laeubi
Copy link
Copy Markdown
Member

laeubi commented Oct 12, 2025

@sratz should we continue on this one?

@sratz
Copy link
Copy Markdown
Member Author

sratz commented Oct 13, 2025

@sratz should we continue on this one?

Yes. The collateral of the cleanups needed in preparation for this should all be addressed in equinox/platform/pde.

Also all checks of this PR were green last time.

I'll rebase again.

In c6edec4 /
https://bugs.eclipse.org/bugs/show_bug.cgi?id=443396 implicit
dependencies were added to every 'eclipse-test-plugin' project to work
around a very special situation: When building the eclipse.platform.ui
repository the test harness is part of the same reactor build as well
and the tests do not explicitly depend on it.

The dependency resolution was then failing because, quote [1],
- Tycho sees that org.eclipse.ui.ide.application is part of the reactor,
  and hence filters all other versions of this bundle from the external
  target platform content.
- The afterProjectsRead dependency resolution doesn't find a dependency
  between the eclipse-test-plugin module and the
  org.eclipse.ui.ide.application module, so it doesn't add it to the
  target platform for the eclipse-test-plugin module. (Adding only the
  "needed" reactor modules instead of all previously built modules is
  something which doesn't give us any benefits today, but it is a
  prerequisite for allowing parallel builds in the future.)
- The resolution of the test runtime fails.

However, this had the undesired side-effect that these artificial
dependencies were added to every other 'eclipse-test-plugin' project as
well, which does not need it.

This caused every 'eclipse-test-plugin' to list all the UI hardness
dependencies in their dependencies tree, even ending up in things like
generated SBOMs, which is incorrect.

With recent improvements to Tycho, especially with eclipse-tycho#2092, the quoted
issue above is not an issue anymore: Instead of filtering out shadowed
units from the external target platform completely, it can now still
access them if needed.

Therefore, this change reverts implicit adding of UI harness
dependencies.

This results in a slight change of behavior when running tests in
'eclipse.platform.ui':
- Before this change, the *project / reactor' version of the test
  harness was used when executing tests that did not themselves depend
  on the workbench.
- After this change, the *external target* version of the test
  harness is used + some warnings are logged.
- If this turns out to be a problem, Eclipse side has to adapt, e.g. by
  adding <extraRequirements> to target-platform-configuration in
  eclipse.platform.releng.aggregator/eclipse-platform-parent/pom.xml,
  restoring the previous Tycho behavior - but only at the place where it
  is actually needed.

[1] https://bugs.eclipse.org/bugs/show_bug.cgi?id=443396#c8

Fixes eclipse-tycho#5349.
@sratz sratz force-pushed the test-plugin-ui-hardness-deps branch from 7fa6c2b to 52eabce Compare October 13, 2025 07:21
@laeubi
Copy link
Copy Markdown
Member

laeubi commented Oct 13, 2025

@sratz by the way if you like you can try out my brand new testing plugin for upcoming Tycho. If you are using structured builds, you can even try to use regular eclipse-plugin packaging and enable it for those instead as an extra execution. That would resolve your issue right away :-)

@sratz
Copy link
Copy Markdown
Member Author

sratz commented Oct 13, 2025

@sratz by the way if you like you can try out my brand new testing plugin for upcoming Tycho. If you are using structured builds, you can even try to use regular eclipse-plugin packaging and enable it for those instead as an extra execution. That would resolve your issue right away :-)

That looks interesting.

We are currently a) stuck on JUnit4 tests with extensive use of Rules and Runners. I'll see if that would even work.

We are also using eclipse-test-plugin packaging, but I guess this is only relevant for the default mojo binding, so I should be able to just change that to eclipse-plugin anyways.

Nevertheless, I think it makes sense to follow-up on this PR as changing the classpath / target platform for eclipse-test-plugins like this is strange either way.

Tests are again green (macOS failure appears to be unrelated).

WDYT?

@laeubi
Copy link
Copy Markdown
Member

laeubi commented Oct 13, 2025

We are currently a) stuck on JUnit4 tests with extensive use of Rules and Runners. I'll see if that would even work.

It should work using the vintage engine then.

Tests are again green (macOS failure appears to be unrelated).

Then lets merge and see what happens ;-)

@laeubi laeubi merged commit ca68b09 into eclipse-tycho:main Oct 13, 2025
13 of 15 checks passed
@sratz
Copy link
Copy Markdown
Member Author

sratz commented Oct 15, 2025

Then lets merge and see what happens ;-)

Is 6.0.0-SNAPSHOT used anywhere already besides in Tycho's CI builds for platform/SWT?

Is this change something we should backport to 5.x (I guess it'll be a while before we reach a 6.0.0 stable)?

@sratz sratz deleted the test-plugin-ui-hardness-deps branch October 15, 2025 10:14
@laeubi
Copy link
Copy Markdown
Member

laeubi commented Oct 15, 2025

Is 6.0.0-SNAPSHOT used anywhere already besides in Tycho's CI builds for platform/SWT?

Not that I'm aware of any.

Is this change something we should backport to 5.x

Can we somehow make this only be enabled by a user property or configuration? e.g. if we have the maven project at hand?

(I guess it'll be a while before we reach a 6.0.0 stable)?

At least there is nothing planned yet.

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.

P2ResolverImpl pollutes 'eclipse-test-plugin' artifacts with artificial test harness dependencies

3 participants