Skip to content

Commit f588de6

Browse files
laeubitrancexpress
andcommitted
Centralize code used in two places to compute JUnit requirements
Currently we have almost identical code in JUnitLaunchConfigurationDelegate and JUnitPluginLaunchConfigurationDelegate to compute the JUnit requirements. This now extract the code into a central place JUnitLaunchRequirements for consistency and maintenance. Co-authored-by: Simeon Andreev <[email protected]>
1 parent 5f0997f commit f588de6

File tree

7 files changed

+111
-149
lines changed

7 files changed

+111
-149
lines changed
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
Javadoc generation options have changed for 4.38
1+
Javadoc generation options have changed for 4.38
2+
Removed non reference method from public API class
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2006, 2025 IBM Corporation and others.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* IBM Corporation - initial API and implementation
13+
*******************************************************************************/
14+
package org.eclipse.pde.internal.launching;
15+
16+
import java.util.ArrayList;
17+
import java.util.Collection;
18+
import java.util.Collections;
19+
import java.util.Comparator;
20+
import java.util.HashSet;
21+
import java.util.LinkedHashSet;
22+
import java.util.List;
23+
import java.util.Map;
24+
import java.util.Set;
25+
import java.util.stream.Collectors;
26+
27+
import org.eclipse.core.runtime.CoreException;
28+
import org.eclipse.core.runtime.Status;
29+
import org.eclipse.debug.core.ILaunchConfiguration;
30+
import org.eclipse.osgi.service.resolver.BundleDescription;
31+
import org.eclipse.osgi.util.NLS;
32+
import org.eclipse.pde.core.plugin.IPluginModelBase;
33+
import org.eclipse.pde.core.plugin.PluginRegistry;
34+
import org.eclipse.pde.internal.core.DependencyManager;
35+
import org.eclipse.pde.internal.core.PDECore;
36+
import org.eclipse.pde.internal.launching.launcher.BundleLauncherHelper;
37+
38+
public class JUnitLaunchRequirements {
39+
40+
public static final String JUNIT4_JDT_RUNTIME_PLUGIN = "org.eclipse.jdt.junit4.runtime"; //$NON-NLS-1$
41+
public static final String JUNIT5_JDT_RUNTIME_PLUGIN = "org.eclipse.jdt.junit5.runtime"; //$NON-NLS-1$
42+
43+
public static void addRequiredJunitRuntimePlugins(ILaunchConfiguration configuration, Map<String, List<IPluginModelBase>> allBundles, Map<IPluginModelBase, String> allModels) throws CoreException {
44+
Set<String> requiredPlugins = new LinkedHashSet<>(getRequiredJunitRuntimeEclipsePlugins(configuration));
45+
46+
if (allBundles.containsKey("junit-platform-runner")) { //$NON-NLS-1$
47+
// add launcher and jupiter.engine to support @RunWith(JUnitPlatform.class)
48+
requiredPlugins.add("junit-platform-launcher"); //$NON-NLS-1$
49+
requiredPlugins.add("junit-jupiter-engine"); //$NON-NLS-1$
50+
}
51+
52+
Set<BundleDescription> addedRequirements = new HashSet<>();
53+
addAbsentRequirements(requiredPlugins, addedRequirements, allBundles, allModels);
54+
55+
Set<BundleDescription> requirementsOfRequirements = DependencyManager.findRequirementsClosure(addedRequirements);
56+
Set<String> rorIds = requirementsOfRequirements.stream().map(BundleDescription::getSymbolicName).collect(Collectors.toSet());
57+
addAbsentRequirements(rorIds, null, allBundles, allModels);
58+
}
59+
60+
@SuppressWarnings("restriction")
61+
public static Collection<String> getRequiredJunitRuntimeEclipsePlugins(ILaunchConfiguration configuration) {
62+
org.eclipse.jdt.internal.junit.launcher.ITestKind testKind = org.eclipse.jdt.internal.junit.launcher.JUnitLaunchConfigurationConstants.getTestRunnerKind(configuration);
63+
if (testKind.isNull()) {
64+
return Collections.emptyList();
65+
}
66+
List<String> plugins = new ArrayList<>();
67+
plugins.add("org.eclipse.pde.junit.runtime"); //$NON-NLS-1$
68+
69+
if (org.eclipse.jdt.internal.junit.launcher.TestKindRegistry.JUNIT4_TEST_KIND_ID.equals(testKind.getId())) {
70+
plugins.add("org.eclipse.jdt.junit4.runtime"); //$NON-NLS-1$
71+
} else if (org.eclipse.jdt.internal.junit.launcher.TestKindRegistry.JUNIT5_TEST_KIND_ID.equals(testKind.getId())) {
72+
plugins.add("org.eclipse.jdt.junit5.runtime"); //$NON-NLS-1$
73+
}
74+
return plugins;
75+
}
76+
77+
private static void addAbsentRequirements(Collection<String> requirements, Set<BundleDescription> addedRequirements, Map<String, List<IPluginModelBase>> allBundles, Map<IPluginModelBase, String> allModels) throws CoreException {
78+
for (String id : requirements) {
79+
List<IPluginModelBase> models = allBundles.computeIfAbsent(id, k -> new ArrayList<>());
80+
if (models.stream().noneMatch(m -> m.getBundleDescription().isResolved())) {
81+
IPluginModelBase model = findRequiredPluginInTargetOrHost(id);
82+
models.add(model);
83+
BundleLauncherHelper.addDefaultStartingBundle(allModels, model);
84+
if (addedRequirements != null) {
85+
addedRequirements.add(model.getBundleDescription());
86+
}
87+
}
88+
}
89+
}
90+
91+
private static IPluginModelBase findRequiredPluginInTargetOrHost(String id) throws CoreException {
92+
IPluginModelBase model = PluginRegistry.findModel(id);
93+
if (model == null || !model.getBundleDescription().isResolved()) {
94+
// prefer bundle from host over unresolved bundle from target
95+
model = PDECore.getDefault().findPluginInHost(id).max(Comparator.comparing(p -> p.getBundleDescription().getVersion())).orElse(null);
96+
}
97+
if (model == null) {
98+
throw new CoreException(Status.error(NLS.bind(PDEMessages.JUnitLaunchConfiguration_error_missingPlugin, id)));
99+
}
100+
return model;
101+
}
102+
}

ui/org.eclipse.pde.launching/src/org/eclipse/pde/launching/JUnitLaunchConfigurationDelegate.java

Lines changed: 2 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,12 @@
2424
import java.nio.file.Path;
2525
import java.util.ArrayList;
2626
import java.util.Arrays;
27-
import java.util.Collection;
2827
import java.util.Collections;
2928
import java.util.Comparator;
30-
import java.util.HashSet;
3129
import java.util.LinkedHashMap;
32-
import java.util.LinkedHashSet;
3330
import java.util.List;
3431
import java.util.Map;
3532
import java.util.Properties;
36-
import java.util.Set;
3733
import java.util.jar.JarOutputStream;
3834
import java.util.jar.Manifest;
3935
import java.util.stream.Collectors;
@@ -58,7 +54,6 @@
5854
import org.eclipse.jdt.launching.IVMInstall;
5955
import org.eclipse.jdt.launching.IVMRunner;
6056
import org.eclipse.jdt.launching.JavaRuntime;
61-
import org.eclipse.osgi.service.resolver.BundleDescription;
6257
import org.eclipse.osgi.util.ManifestElement;
6358
import org.eclipse.osgi.util.NLS;
6459
import org.eclipse.pde.core.plugin.IFragment;
@@ -69,14 +64,13 @@
6964
import org.eclipse.pde.core.plugin.TargetPlatform;
7065
import org.eclipse.pde.internal.build.IPDEBuildConstants;
7166
import org.eclipse.pde.internal.core.ClasspathHelper;
72-
import org.eclipse.pde.internal.core.DependencyManager;
7367
import org.eclipse.pde.internal.core.ICoreConstants;
74-
import org.eclipse.pde.internal.core.PDECore;
7568
import org.eclipse.pde.internal.core.TargetPlatformHelper;
7669
import org.eclipse.pde.internal.core.bnd.PdeProjectAnalyzer;
7770
import org.eclipse.pde.internal.core.util.CoreUtility;
7871
import org.eclipse.pde.internal.core.util.VersionUtil;
7972
import org.eclipse.pde.internal.launching.IPDEConstants;
73+
import org.eclipse.pde.internal.launching.JUnitLaunchRequirements;
8074
import org.eclipse.pde.internal.launching.PDELaunchingPlugin;
8175
import org.eclipse.pde.internal.launching.PDEMessages;
8276
import org.eclipse.pde.internal.launching.launcher.BundleLauncherHelper;
@@ -393,18 +387,6 @@ protected String getApplication(ILaunchConfiguration configuration) {
393387
return application;
394388
}
395389

396-
private IPluginModelBase findRequiredPluginInTargetOrHost(String id) throws CoreException {
397-
IPluginModelBase model = PluginRegistry.findModel(id);
398-
if (model == null || !model.getBundleDescription().isResolved()) {
399-
// prefer bundle from host over unresolved bundle from target
400-
model = PDECore.getDefault().findPluginInHost(id).max(Comparator.comparing(p -> p.getBundleDescription().getVersion())).orElse(null);
401-
}
402-
if (model == null) {
403-
abort(NLS.bind(PDEMessages.JUnitLaunchConfiguration_error_missingPlugin, id), null, IStatus.OK);
404-
}
405-
return model;
406-
}
407-
408390
@Override
409391
public String getProgramArguments(ILaunchConfiguration configuration) throws CoreException {
410392
return LaunchArgumentsHelper.getUserProgramArguments(configuration);
@@ -537,7 +519,7 @@ protected void preLaunchCheck(ILaunchConfiguration configuration, ILaunch launch
537519
launchMode = launch.getLaunchMode();
538520

539521
// implicitly add the plug-ins required for JUnit testing if necessary
540-
addRequiredJunitRuntimePlugins(configuration);
522+
JUnitLaunchRequirements.addRequiredJunitRuntimePlugins(configuration, fAllBundles, fModels);
541523

542524
String attribute = launch.getAttribute(PDE_JUNIT_SHOW_COMMAND);
543525
boolean isShowCommand = false;
@@ -558,58 +540,6 @@ protected void preLaunchCheck(ILaunchConfiguration configuration, ILaunch launch
558540
synchronizeManifests(configuration, subMonitor.split(1));
559541
}
560542

561-
private void addRequiredJunitRuntimePlugins(ILaunchConfiguration configuration) throws CoreException {
562-
Set<String> requiredPlugins = new LinkedHashSet<>(getRequiredJunitRuntimePlugins(configuration));
563-
564-
if (fAllBundles.containsKey("junit-platform-runner") || fAllBundles.containsKey("org.junit.platform.runner")) { //$NON-NLS-1$ //$NON-NLS-2$
565-
// add launcher and jupiter.engine to support @RunWith(JUnitPlatform.class)
566-
requiredPlugins.add("junit-platform-launcher"); //$NON-NLS-1$
567-
requiredPlugins.add("junit-jupiter-engine"); //$NON-NLS-1$
568-
}
569-
Set<BundleDescription> addedRequirements = new HashSet<>();
570-
addAbsentRequirements(requiredPlugins, addedRequirements);
571-
572-
Set<BundleDescription> requirementsOfRequirements = DependencyManager.findRequirementsClosure(addedRequirements);
573-
Set<String> rorIds = requirementsOfRequirements.stream().map(BundleDescription::getSymbolicName).collect(Collectors.toSet());
574-
addAbsentRequirements(rorIds, null);
575-
}
576-
577-
private void addAbsentRequirements(Collection<String> requirements, Set<BundleDescription> addedRequirements) throws CoreException {
578-
for (String id : requirements) {
579-
List<IPluginModelBase> models = fAllBundles.computeIfAbsent(id, k -> new ArrayList<>());
580-
if (models.stream().noneMatch(m -> m.getBundleDescription().isResolved())) {
581-
IPluginModelBase model = findRequiredPluginInTargetOrHost(id);
582-
models.add(model);
583-
BundleLauncherHelper.addDefaultStartingBundle(fModels, model);
584-
if (addedRequirements != null) {
585-
addedRequirements.add(model.getBundleDescription());
586-
}
587-
}
588-
}
589-
}
590-
591-
/**
592-
* @noreference This method is not intended to be referenced by clients.
593-
* @param configuration non null config
594-
* @return required plugins
595-
*/
596-
@SuppressWarnings("restriction")
597-
public static Collection<String> getRequiredJunitRuntimePlugins(ILaunchConfiguration configuration) {
598-
org.eclipse.jdt.internal.junit.launcher.ITestKind testKind = org.eclipse.jdt.internal.junit.launcher.JUnitLaunchConfigurationConstants.getTestRunnerKind(configuration);
599-
if (testKind.isNull()) {
600-
return Collections.emptyList();
601-
}
602-
List<String> plugins = new ArrayList<>();
603-
plugins.add("org.eclipse.pde.junit.runtime"); //$NON-NLS-1$
604-
605-
if (org.eclipse.jdt.internal.junit.launcher.TestKindRegistry.JUNIT4_TEST_KIND_ID.equals(testKind.getId())) {
606-
plugins.add("org.eclipse.jdt.junit4.runtime"); //$NON-NLS-1$
607-
} else if (org.eclipse.jdt.internal.junit.launcher.TestKindRegistry.JUNIT5_TEST_KIND_ID.equals(testKind.getId())) {
608-
plugins.add("org.eclipse.jdt.junit5.runtime"); //$NON-NLS-1$
609-
}
610-
return plugins;
611-
}
612-
613543
/**
614544
* Checks for old-style plugin.xml files that have become stale since the last launch.
615545
* For any stale plugin.xml files found, the corresponding MANIFEST.MF is deleted

ui/org.eclipse.pde.ui/.settings/.api_filters

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -95,15 +95,6 @@
9595
</message_arguments>
9696
</filter>
9797
</resource>
98-
<resource path="src/org/eclipse/pde/internal/ui/launcher/PluginBlock.java" type="org.eclipse.pde.internal.ui.launcher.PluginBlock">
99-
<filter id="640712815">
100-
<message_arguments>
101-
<message_argument value="JUnitLaunchConfigurationDelegate"/>
102-
<message_argument value="PluginBlock"/>
103-
<message_argument value="getRequiredJunitRuntimePlugins(ILaunchConfiguration)"/>
104-
</message_arguments>
105-
</filter>
106-
</resource>
10798
<resource path="src/org/eclipse/pde/internal/ui/refactoring/RenamePluginProcessor.java" type="org.eclipse.pde.internal.ui.refactoring.RenamePluginProcessor">
10899
<filter id="572522506">
109100
<message_arguments>

ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/PluginBlock.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@
2727
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
2828
import org.eclipse.pde.core.plugin.IPluginModelBase;
2929
import org.eclipse.pde.core.plugin.PluginRegistry;
30+
import org.eclipse.pde.internal.launching.JUnitLaunchRequirements;
3031
import org.eclipse.pde.internal.launching.launcher.BundleLauncherHelper;
3132
import org.eclipse.pde.internal.launching.launcher.EclipsePluginValidationOperation;
3233
import org.eclipse.pde.internal.launching.launcher.LaunchValidationOperation;
3334
import org.eclipse.pde.internal.launching.launcher.RequirementHelper;
3435
import org.eclipse.pde.internal.ui.PDEPlugin;
3536
import org.eclipse.pde.launching.IPDELauncherConstants;
36-
import org.eclipse.pde.launching.JUnitLaunchConfigurationDelegate;
3737
import org.eclipse.pde.ui.launcher.AbstractLauncherTab;
3838

3939
public class PluginBlock extends AbstractPluginBlock {
@@ -165,7 +165,8 @@ protected void addRequiredPlugins() {
165165
// Check that the application or product we are launching has its requirements included
166166
try {
167167
List<String> requiredIds = RequirementHelper.getApplicationLaunchRequirements(fLaunchConfig);
168-
Collection<String> requiredPlugins = JUnitLaunchConfigurationDelegate.getRequiredJunitRuntimePlugins(fLaunchConfig);
168+
Collection<String> requiredPlugins = JUnitLaunchRequirements
169+
.getRequiredJunitRuntimeEclipsePlugins(fLaunchConfig);
169170
Stream.concat(requiredPlugins.stream(), requiredIds.stream()).forEach(requiredId -> {
170171
// see if launcher plugin is already included
171172
IPluginModelBase base = findPlugin(requiredId);

ui/org.eclipse.pde.unittest.junit/.settings/.api_filters

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,6 @@
88
</message_arguments>
99
</filter>
1010
</resource>
11-
<resource path="src/org/eclipse/pde/unittest/junit/launcher/JUnitPluginLaunchConfigurationDelegate.java" type="org.eclipse.pde.unittest.junit.launcher.JUnitPluginLaunchConfigurationDelegate">
12-
<filter id="640712815">
13-
<message_arguments>
14-
<message_argument value="JUnitLaunchConfigurationDelegate"/>
15-
<message_argument value="JUnitPluginLaunchConfigurationDelegate"/>
16-
<message_argument value="getRequiredJunitRuntimePlugins(ILaunchConfiguration)"/>
17-
</message_arguments>
18-
</filter>
19-
</resource>
2011
<resource path="src/org/eclipse/pde/unittest/junit/launcher/JUnitPluginTestTab.java" type="org.eclipse.pde.unittest.junit.launcher.JUnitPluginTestTab">
2112
<filter id="571473929">
2213
<message_arguments>

0 commit comments

Comments
 (0)