Skip to content

Commit 5629147

Browse files
committed
Support JUnit 5 and JUnit 6 for org.eclipse.pde.core.requiredPlugins
When a plug-in requires the JUnit bundle junit-jupiter-api, if the target platform contains both JUnit 5 and JUnit 6, RequiredPluginsClasspathContainer will put JUnit 6 on the JDT classpath. This is problematic, since a plug-in cannot then specify JUnit 5, even when constraining the version of junit-jupiter-api. This change checks what version of junit-jupiter-api is required, then adds only that version of JUnit bundles to the container. Fixes: #2007
1 parent df089ec commit 5629147

File tree

1 file changed

+58
-10
lines changed

1 file changed

+58
-10
lines changed

ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/RequiredPluginsClasspathContainer.java

Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import java.util.Queue;
3232
import java.util.Set;
3333
import java.util.TreeMap;
34+
import java.util.function.Function;
3435
import java.util.stream.Stream;
3536

3637
import org.eclipse.core.resources.IFile;
@@ -65,6 +66,8 @@
6566
import org.eclipse.pde.internal.core.bnd.BndProjectManager;
6667
import org.eclipse.pde.internal.core.ibundle.IBundlePluginModelBase;
6768
import org.eclipse.pde.internal.core.natures.BndProject;
69+
import org.osgi.framework.Version;
70+
import org.osgi.framework.VersionRange;
6871
import org.osgi.resource.Resource;
6972

7073
import aQute.bnd.build.Container;
@@ -74,10 +77,14 @@
7477

7578
class RequiredPluginsClasspathContainer {
7679

80+
private static final VersionRange JUNIT5_VERSION_RANGE = new VersionRange("[1,6)");
81+
private static final VersionRange JUNIT6_VERSION_RANGE = new VersionRange("[6,7)");
82+
7783
@SuppressWarnings("nls")
7884
private static final Set<String> JUNIT5_RUNTIME_PLUGINS = Set.of("org.junit", //
7985
"junit-jupiter-engine", // BSN of the bundle from Maven-Central
8086
"org.junit.jupiter.engine"); // BSN of the bundle from Eclipse-Orbit
87+
8188
@SuppressWarnings("nls")
8289
private static final Set<String> JUNIT5_API_PLUGINS = Set.of( //
8390
"junit-jupiter-api", // BSN of the bundle from Maven-Central
@@ -87,6 +94,7 @@ class RequiredPluginsClasspathContainer {
8794
private final IBuild fBuild;
8895

8996
private List<BundleDescription> junit5RuntimeClosure;
97+
private List<BundleDescription> junit6RuntimeClosure;
9098
private IClasspathEntry[] fEntries;
9199
private boolean addImportedPackages;
92100

@@ -575,20 +583,35 @@ protected void addExtraClasspathEntries(List<IClasspathEntry> entries, String[]
575583
*/
576584
private void addJunit5RuntimeDependencies(Set<BundleDescription> added, List<IClasspathEntry> entries)
577585
throws CoreException {
578-
if (!containsJunit5Dependency(added)) {
586+
Optional<Integer> junitVersion = getHighestJunitVersion(added);
587+
if (junitVersion.isEmpty()) {
579588
return;
580589
}
581-
582-
if (junit5RuntimeClosure == null) {
583-
junit5RuntimeClosure = collectJunit5RuntimeRequirements();
590+
int majorVersion = junitVersion.get().intValue();
591+
List<BundleDescription> runtimeClosure = null;
592+
if (majorVersion == 5) {
593+
if (junit5RuntimeClosure == null) {
594+
junit5RuntimeClosure = collectJunit5RuntimeRequirements();
595+
}
596+
runtimeClosure = junit5RuntimeClosure;
597+
}
598+
if (majorVersion == 6) {
599+
if (junit6RuntimeClosure == null) {
600+
junit6RuntimeClosure = collectJunit6RuntimeRequirements();
601+
}
602+
runtimeClosure = junit6RuntimeClosure;
603+
}
604+
if (runtimeClosure == null) {
605+
// we don't know this JUnit version
606+
return;
584607
}
585608

586609
String id = fModel.getPluginBase().getId();
587-
if (id != null && junit5RuntimeClosure.stream().map(BundleDescription::getSymbolicName).anyMatch(id::equals)) {
610+
if (id != null && runtimeClosure.stream().map(BundleDescription::getSymbolicName).anyMatch(id::equals)) {
588611
return; // never extend the classpath of a junit bundle
589612
}
590613

591-
for (BundleDescription desc : junit5RuntimeClosure) {
614+
for (BundleDescription desc : runtimeClosure) {
592615
if (added.contains(desc)) {
593616
continue; // bundle has explicit dependency
594617
}
@@ -599,12 +622,19 @@ private void addJunit5RuntimeDependencies(Set<BundleDescription> added, List<ICl
599622
}
600623
}
601624

602-
private boolean containsJunit5Dependency(Collection<BundleDescription> dependencies) {
603-
return dependencies.stream().map(BundleDescription::getSymbolicName).anyMatch(JUNIT5_API_PLUGINS::contains);
625+
private static List<BundleDescription> collectJunit5RuntimeRequirements() {
626+
return collectJunitRuntimeRequirements(JUNIT5_RUNTIME_PLUGINS,
627+
RequiredPluginsClasspathContainer::findJunit5BundleModel);
604628
}
605629

606-
private static List<BundleDescription> collectJunit5RuntimeRequirements() {
607-
List<BundleDescription> roots = JUNIT5_RUNTIME_PLUGINS.stream().map(PluginRegistry::findModel)
630+
private static List<BundleDescription> collectJunit6RuntimeRequirements() {
631+
return collectJunitRuntimeRequirements(JUNIT5_RUNTIME_PLUGINS,
632+
RequiredPluginsClasspathContainer::findJunit6BundleModel);
633+
}
634+
635+
private static List<BundleDescription> collectJunitRuntimeRequirements(Collection<String> junitRuntimePlugins,
636+
Function<String, IPluginModelBase> idToModel) {
637+
List<BundleDescription> roots = junitRuntimePlugins.stream().map(idToModel)
608638
.filter(Objects::nonNull).filter(IPluginModelBase::isEnabled)
609639
.map(IPluginModelBase::getBundleDescription).toList();
610640
Set<BundleDescription> closure = DependencyManager.findRequirementsClosure(roots,
@@ -614,6 +644,14 @@ private static List<BundleDescription> collectJunit5RuntimeRequirements() {
614644
.sorted(Comparator.comparing(BundleDescription::getSymbolicName)).toList();
615645
}
616646

647+
private static IPluginModelBase findJunit5BundleModel(String bundleId) {
648+
return PluginRegistry.findModel(bundleId, JUNIT5_VERSION_RANGE);
649+
}
650+
651+
private static IPluginModelBase findJunit6BundleModel(String bundleId) {
652+
return PluginRegistry.findModel(bundleId, JUNIT6_VERSION_RANGE);
653+
}
654+
617655
private void addSecondaryDependencies(BundleDescription desc, Set<BundleDescription> added,
618656
List<IClasspathEntry> entries) {
619657
try {
@@ -716,4 +754,14 @@ private void addExtraLibrary(IPath path, IPluginModelBase model, List<IClasspath
716754
}
717755
}
718756

757+
private static Optional<Integer> getHighestJunitVersion(Collection<BundleDescription> bundleDescriptions) {
758+
Optional<Version> highestVersion = bundleDescriptions.stream()
759+
.filter(RequiredPluginsClasspathContainer::isJunit5ApiBundle).map(BundleDescription::getVersion)
760+
.max(Version::compareTo);
761+
return highestVersion.map(Version::getMajor);
762+
}
763+
764+
private static boolean isJunit5ApiBundle(BundleDescription bundleDescription) {
765+
return JUNIT5_API_PLUGINS.contains(bundleDescription.getSymbolicName());
766+
}
719767
}

0 commit comments

Comments
 (0)