Skip to content

Commit 4bfb13b

Browse files
committed
Move the search from the dialog to the DetectVMInstallationsJob
and use that search method in the test to discover and dispose required jvms
1 parent 3eefc70 commit 4bfb13b

7 files changed

Lines changed: 127 additions & 84 deletions

File tree

org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/MultiReleaseLaunchTests.java

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,51 +13,87 @@
1313
*******************************************************************************/
1414
package org.eclipse.jdt.debug.tests.core;
1515

16+
import java.io.File;
1617
import java.io.StringReader;
1718
import java.util.ArrayList;
1819
import java.util.Collection;
20+
import java.util.HashSet;
1921
import java.util.Iterator;
2022
import java.util.List;
2123
import java.util.Properties;
24+
import java.util.Set;
25+
import java.util.UUID;
2226

27+
import org.eclipse.core.runtime.NullProgressMonitor;
2328
import org.eclipse.debug.core.DebugPlugin;
2429
import org.eclipse.debug.core.ILaunchConfiguration;
2530
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
2631
import org.eclipse.debug.ui.DebugUITools;
2732
import org.eclipse.jdt.core.IJavaProject;
2833
import org.eclipse.jdt.debug.core.IJavaDebugTarget;
2934
import org.eclipse.jdt.debug.tests.ui.AbstractDebugUiTests;
35+
import org.eclipse.jdt.internal.launching.DetectVMInstallationsJob;
3036
import org.eclipse.jdt.launching.IVMInstall;
3137
import org.eclipse.jdt.launching.IVMInstall2;
3238
import org.eclipse.jdt.launching.IVMInstallType;
3339
import org.eclipse.jdt.launching.JavaRuntime;
40+
import org.eclipse.jdt.launching.VMStandin;
3441
import org.eclipse.jface.text.IDocument;
3542
import org.eclipse.ui.console.IConsole;
3643
import org.eclipse.ui.console.TextConsole;
3744

3845
/**
3946
* <b>IMPORTANT</b> This test requires some different JVM installs to be present (see {@link #JAVA_11}, {@link #JAVA_17}, {@link #JAVA_21})) if such
40-
* JVMs can not be found, the test will fail!
47+
* JVMs can not be found, the test will fail! One can specify a basedir to search for such jvms with the {@link #JVM_SEARCH_BASE} system property.
4148
*/
4249
public class MultiReleaseLaunchTests extends AbstractDebugUiTests {
4350

51+
private static final String JVM_SEARCH_BASE = "MultiReleaseLaunchTests.rootDir";
4452
private static final RequiredJavaVersion JAVA_11 = new RequiredJavaVersion(11, 16);
4553
private static final RequiredJavaVersion JAVA_17 = new RequiredJavaVersion(17, 20);
4654
private static final RequiredJavaVersion JAVA_21 = new RequiredJavaVersion(21, Integer.MAX_VALUE);
4755

56+
private List<Runnable> disposeVms = new ArrayList<>();
57+
4858
public MultiReleaseLaunchTests(String name) {
4959
super(name);
5060
}
5161

5262
@Override
5363
protected void setUp() throws Exception {
5464
super.setUp();
65+
final Set<File> existingLocations = new HashSet<>();
5566
List<RequiredJavaVersion> requiredJavaVersions = new ArrayList<>(List.of(JAVA_11, JAVA_17, JAVA_21));
56-
removeExistingJavaVersions(requiredJavaVersions);
67+
removeExistingJavaVersions(requiredJavaVersions, existingLocations);
68+
if (!requiredJavaVersions.isEmpty()) {
69+
final File rootDir = new File(System.getProperty(JVM_SEARCH_BASE, "/opt/tools/java/openjdk/"));
70+
final List<File> locations = new ArrayList<>();
71+
final List<IVMInstallType> types = new ArrayList<>();
72+
DetectVMInstallationsJob.search(rootDir, locations, types, existingLocations, new NullProgressMonitor());
73+
for (int i = 0; i < locations.size(); i++) {
74+
File location = locations.get(i);
75+
IVMInstallType type = types.get(i);
76+
String id = "MultiReleaseLaunchTests-" + UUID.randomUUID() + "-" + i;
77+
VMStandin workingCopy = new VMStandin(type, id);
78+
workingCopy.setInstallLocation(location);
79+
IVMInstall install = workingCopy.convertToRealVM();
80+
if (removeIfMatch(requiredJavaVersions, install)) {
81+
disposeVms.add(() -> type.disposeVMInstall(id));
82+
} else {
83+
type.disposeVMInstall(id);
84+
}
85+
}
86+
}
5787
assertTrue("The following java versions are required by this test but can not be found: "
5888
+ requiredJavaVersions, requiredJavaVersions.isEmpty());
5989
}
6090

91+
@Override
92+
protected void tearDown() throws Exception {
93+
super.tearDown();
94+
disposeVms.forEach(Runnable::run);
95+
}
96+
6197
@Override
6298
protected IJavaProject getProjectContext() {
6399
return getMultireleaseProject();
@@ -110,23 +146,29 @@ private static int getJavaVersion(IVMInstall install) {
110146
return -1;
111147
}
112148

113-
private static void removeExistingJavaVersions(Collection<RequiredJavaVersion> requiredJavaVersions) {
149+
private static void removeExistingJavaVersions(Collection<RequiredJavaVersion> requiredJavaVersions, Set<File> existingLocations) {
114150
IVMInstallType[] installTypes = JavaRuntime.getVMInstallTypes();
115151
for (IVMInstallType installType : installTypes) {
116152
IVMInstall[] vmInstalls = installType.getVMInstalls();
117153
for (IVMInstall install : vmInstalls) {
118154
if (requiredJavaVersions.isEmpty()) {
119155
return;
120156
}
121-
int javaVersion = getJavaVersion(install);
122-
for (Iterator<RequiredJavaVersion> iterator = requiredJavaVersions.iterator(); iterator.hasNext();) {
123-
if (iterator.next().matches(javaVersion)) {
124-
iterator.remove();
125-
break;
126-
}
127-
}
157+
existingLocations.add(install.getInstallLocation());
158+
removeIfMatch(requiredJavaVersions, install);
159+
}
160+
}
161+
}
162+
163+
protected static boolean removeIfMatch(Collection<RequiredJavaVersion> requiredJavaVersions, IVMInstall install) {
164+
int javaVersion = getJavaVersion(install);
165+
for (Iterator<RequiredJavaVersion> iterator = requiredJavaVersions.iterator(); iterator.hasNext();) {
166+
if (iterator.next().matches(javaVersion)) {
167+
iterator.remove();
168+
return true;
128169
}
129170
}
171+
return false;
130172
}
131173

132174
private static record RequiredJavaVersion(int from, int to) {

org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/InstalledJREsBlock.java

Lines changed: 1 addition & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323

2424
import org.eclipse.core.runtime.CoreException;
2525
import org.eclipse.core.runtime.IProgressMonitor;
26-
import org.eclipse.core.runtime.IStatus;
2726
import org.eclipse.core.runtime.ListenerList;
2827
import org.eclipse.core.runtime.Platform;
2928
import org.eclipse.core.runtime.SubMonitor;
@@ -910,7 +909,7 @@ protected void search() {
910909
@Override
911910
public void run(IProgressMonitor monitor) {
912911
monitor.beginTask(JREMessages.InstalledJREsBlock_11, IProgressMonitor.UNKNOWN);
913-
search(rootDir, locations, types, exstingLocations, monitor);
912+
DetectVMInstallationsJob.search(rootDir, locations, types, exstingLocations, monitor);
914913
monitor.done();
915914
}
916915
};
@@ -1031,75 +1030,6 @@ private String createUniqueId(IVMInstallType vmType) {
10311030
return id;
10321031
}
10331032

1034-
/**
1035-
* Searches the specified directory recursively for installed VMs, adding each
1036-
* detected VM to the <code>found</code> list. Any directories specified in
1037-
* the <code>ignore</code> are not traversed.
1038-
*/
1039-
protected void search(File directory, List<File> found, List<IVMInstallType> types, Set<File> ignore, IProgressMonitor monitor) {
1040-
if (monitor.isCanceled()) {
1041-
return;
1042-
}
1043-
1044-
String[] fileNames = directory.list();
1045-
if (fileNames == null) {
1046-
return; // not a directory
1047-
}
1048-
List<String> names = new ArrayList<>();
1049-
names.add(null); // self
1050-
names.addAll(List.of(fileNames));
1051-
List<File> subDirs = new ArrayList<>();
1052-
for (String name : names) {
1053-
if (monitor.isCanceled()) {
1054-
return;
1055-
}
1056-
File file = name == null ? directory : new File(directory, name);
1057-
monitor.subTask(NLS.bind(JREMessages.InstalledJREsBlock_14, Integer.toString(found.size()),
1058-
file.toPath().normalize().toAbsolutePath().toString().replace("&", "&&") )); // @see bug 29855 //$NON-NLS-1$ //$NON-NLS-2$
1059-
IVMInstallType[] vmTypes = JavaRuntime.getVMInstallTypes();
1060-
if (file.isDirectory()) {
1061-
if (ignore.add(file)) {
1062-
boolean validLocation = false;
1063-
1064-
// Take the first VM install type that claims the location as a
1065-
// valid VM install. VM install types should be smart enough to not
1066-
// claim another type's VM, but just in case...
1067-
for (int j = 0; j < vmTypes.length; j++) {
1068-
if (monitor.isCanceled()) {
1069-
return;
1070-
}
1071-
IVMInstallType type = vmTypes[j];
1072-
IStatus status = type.validateInstallLocation(file);
1073-
if (status.isOK()) {
1074-
String filePath = file.getPath();
1075-
int index = filePath.lastIndexOf(File.separatorChar);
1076-
File newFile = file;
1077-
// remove bin folder from install location as java executables are found only under bin for Java 9 and above
1078-
if (index > 0 && filePath.substring(index + 1).equals("bin")) { //$NON-NLS-1$
1079-
newFile = new File(filePath.substring(0, index));
1080-
}
1081-
found.add(newFile);
1082-
types.add(type);
1083-
validLocation = true;
1084-
break;
1085-
}
1086-
}
1087-
if (!validLocation) {
1088-
subDirs.add(file);
1089-
}
1090-
}
1091-
}
1092-
}
1093-
while (!subDirs.isEmpty()) {
1094-
File subDir = subDirs.remove(0);
1095-
search(subDir, found, types, ignore, monitor);
1096-
if (monitor.isCanceled()) {
1097-
return;
1098-
}
1099-
}
1100-
1101-
}
1102-
11031033
/**
11041034
* Sets the checked JRE, possible <code>null</code>
11051035
*

org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/JREMessages.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ public class JREMessages extends NLS {
4545
public static String InstalledJREsBlock_11;
4646
public static String InstalledJREsBlock_12;
4747
public static String InstalledJREsBlock_13;
48-
public static String InstalledJREsBlock_14;
4948
public static String InstalledJREsBlock_15;
5049
public static String InstalledJREsBlock_16;
5150

org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/JREMessages.properties

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ InstalledJREsBlock_10=Directory Selection
3636
InstalledJREsBlock_11=Searching...
3737
InstalledJREsBlock_12=Information
3838
InstalledJREsBlock_13=No JREs found in {0}
39-
InstalledJREsBlock_14=Found {0} - Searching {1}
4039
InstalledJREsBlock_15=Installed &JREs:
4140
InstalledJREsBlock_16=Dupli&cate...
4241
InstalledJREsBlock_19={0} (contributed)

org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/DetectVMInstallationsJob.java

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import org.eclipse.jdt.launching.IVMInstallType;
3939
import org.eclipse.jdt.launching.JavaRuntime;
4040
import org.eclipse.jdt.launching.VMStandin;
41+
import org.eclipse.osgi.util.NLS;
4142

4243
/**
4344
* Lookup for VMs installed in standard or usual locations; and add the existing ones that
@@ -240,6 +241,75 @@ public boolean belongsTo(Object family) {
240241
return family.equals(FAMILY);
241242
}
242243

244+
/**
245+
* Searches the specified directory recursively for installed VMs, adding each
246+
* detected VM to the <code>found</code> list. Any directories specified in
247+
* the <code>ignore</code> are not traversed.
248+
*/
249+
public static void search(File directory, List<File> found, List<IVMInstallType> types, Set<File> ignore, IProgressMonitor monitor) {
250+
if (monitor.isCanceled()) {
251+
return;
252+
}
253+
254+
String[] fileNames = directory.list();
255+
if (fileNames == null) {
256+
return; // not a directory
257+
}
258+
List<String> names = new ArrayList<>();
259+
names.add(null); // self
260+
names.addAll(List.of(fileNames));
261+
List<File> subDirs = new ArrayList<>();
262+
for (String name : names) {
263+
if (monitor.isCanceled()) {
264+
return;
265+
}
266+
File file = name == null ? directory : new File(directory, name);
267+
monitor.subTask(NLS.bind(LaunchingMessages.SearchingJVMs, Integer.toString(found.size()),
268+
file.toPath().normalize().toAbsolutePath().toString().replace("&", "&&") )); // @see bug 29855 //$NON-NLS-1$ //$NON-NLS-2$
269+
IVMInstallType[] vmTypes = JavaRuntime.getVMInstallTypes();
270+
if (file.isDirectory()) {
271+
if (ignore.add(file)) {
272+
boolean validLocation = false;
273+
274+
// Take the first VM install type that claims the location as a
275+
// valid VM install. VM install types should be smart enough to not
276+
// claim another type's VM, but just in case...
277+
for (int j = 0; j < vmTypes.length; j++) {
278+
if (monitor.isCanceled()) {
279+
return;
280+
}
281+
IVMInstallType type = vmTypes[j];
282+
IStatus status = type.validateInstallLocation(file);
283+
if (status.isOK()) {
284+
String filePath = file.getPath();
285+
int index = filePath.lastIndexOf(File.separatorChar);
286+
File newFile = file;
287+
// remove bin folder from install location as java executables are found only under bin for Java 9 and above
288+
if (index > 0 && filePath.substring(index + 1).equals("bin")) { //$NON-NLS-1$
289+
newFile = new File(filePath.substring(0, index));
290+
}
291+
found.add(newFile);
292+
types.add(type);
293+
validLocation = true;
294+
break;
295+
}
296+
}
297+
if (!validLocation) {
298+
subDirs.add(file);
299+
}
300+
}
301+
}
302+
}
303+
while (!subDirs.isEmpty()) {
304+
File subDir = subDirs.remove(0);
305+
search(subDir, found, types, ignore, monitor);
306+
if (monitor.isCanceled()) {
307+
return;
308+
}
309+
}
310+
311+
}
312+
243313
public static void initialize() {
244314
if (Boolean.getBoolean(PROPERTY_DETECT_VM_INSTALLATIONS_JOB_DISABLED)) {
245315
// early exit no need to read preferences or check env variable!

org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/LaunchingMessages.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
public class LaunchingMessages extends NLS {
1919
private static final String BUNDLE_NAME = "org.eclipse.jdt.internal.launching.LaunchingMessages";//$NON-NLS-1$
2020

21+
public static String SearchingJVMs;
22+
2123
public static String AbstractJavaLaunchConfigurationDelegate_Java_project_not_specified_9;
2224
public static String AbstractJavaLaunchConfigurationDelegate_JRE_home_directory_for__0__does_not_exist___1__6;
2325
public static String AbstractJavaLaunchConfigurationDelegate_JRE_home_directory_not_specified_for__0__5;

org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/LaunchingMessages.properties

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,4 +206,5 @@ VMLogging_1=Restoring vm library location:
206206
VMLogging_2=Creating Library with Java Install path:
207207
VMLogging_3=Default Install retrieved:
208208
lookupInstalledJVMs=Detect installed JVMs
209-
configuringJVM=Configuring installed JVM {0}
209+
configuringJVM=Configuring installed JVM {0}
210+
SearchingJVMs=Found {0} - Searching {1}

0 commit comments

Comments
 (0)