Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detect JVM installs at startup #231

Merged
merged 4 commits into from
Jun 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion org.eclipse.jdt.debug.tests/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.jdt.debug.tests; singleton:=true
Bundle-Version: 3.12.0.qualifier
Bundle-Version: 3.12.100.qualifier
Bundle-ClassPath: javadebugtests.jar
Bundle-Activator: org.eclipse.jdt.debug.testplugin.JavaTestPlugin
Bundle-Vendor: %providerName
Expand Down
2 changes: 1 addition & 1 deletion org.eclipse.jdt.debug.tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
</parent>
<groupId>org.eclipse.jdt</groupId>
<artifactId>org.eclipse.jdt.debug.tests</artifactId>
<version>3.12.0-SNAPSHOT</version>
<version>3.12.100-SNAPSHOT</version>
<packaging>eclipse-test-plugin</packaging>
<properties>
<code.ignoredWarnings>${tests.ignoredWarnings}</code.ignoredWarnings>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -364,9 +364,9 @@ private void testOutput(String mainTypeName, String vmArgs, String programArgs,
workingCopy.setAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, env);

IVMInstall vm = JavaRuntime.getVMInstall(get14Project());
assertNotNull("shold be able to get the default VM install from the 1.4 project", vm);
assertNotNull("should be able to get a VM install from the 1.4 project", vm);
if (fUseArgfile) {
assertTrue("test requires a JVM >= 9", JavaRuntime.isModularJava(vm));
workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_JRE_CONTAINER_PATH, JavaRuntime.newJREContainerPath(JavaRuntime.getExecutionEnvironmentsManager().getEnvironment("JavaSE-9")).toString());
}
//workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_JRE_CONTAINER_PATH, JavaRuntime.newJREContainerPath(vm).toPortableString());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ public void testJRELibResolution() throws CoreException {
assertNotNull("no default JRE", vm);
LibraryLocation[] libs = JavaRuntime.getLibraryLocations(vm);
assertTrue("no default libs", libs.length > 0);
assertEquals("Should resolve to location of local JRE", libs[0].getSystemLibraryPath().toOSString().toLowerCase(), resolved[0].getPath().toOSString().toLowerCase());
jjohnstn marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@
*******************************************************************************/
package org.eclipse.jdt.debug.tests.sourcelookup;

import java.io.File;
import java.util.Arrays;
import java.util.function.Predicate;
import java.util.Objects;
import java.util.stream.Stream;

import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.IPath;
Expand All @@ -29,6 +33,10 @@
import org.eclipse.jdt.debug.tests.AbstractDebugTest;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.launching.JavaSourceLookupDirector;
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.launching.environments.IExecutionEnvironment;
import org.junit.After;

/**
* Tests for bug 565462.
Expand All @@ -38,10 +46,33 @@ public class Bug565462Tests extends AbstractDebugTest {
private static final String MODULE_JRE_PROJECT_NAME = "ModuleJREProject";
private static final String NON_MODULE_JRE_PROJECT_NAME = "NonModuleJREProject";

private IExecutionEnvironment javaSE11;
private IVMInstall defaultJavaSE11VM;

public Bug565462Tests(String name) {
super(name);
}

@Override
protected void setUp() throws Exception {
super.setUp();
this.javaSE11 = JavaRuntime.getExecutionEnvironmentsManager().getEnvironment("JavaSE-11");
this.defaultJavaSE11VM = javaSE11.getDefaultVM();
Predicate<IVMInstall> hasSource = vm -> vm != null && vm.getInstallLocation() != null && new File(vm.getInstallLocation(), "lib/src.zip").isFile();
if (!hasSource.test(defaultJavaSE11VM)) {
Stream.of(javaSE11.getCompatibleVMs()).filter(Objects::nonNull).filter(hasSource)
.findAny()
.ifPresent(javaSE11::setDefaultVM);
}
assertTrue("Default VM doesn't have source", hasSource.test(javaSE11.getDefaultVM()));
}

@After
public void tearDown() throws Exception {
javaSE11.setDefaultVM(defaultJavaSE11VM);
super.tearDown();
}

/**
* Test for bug 565462.
*
Expand Down Expand Up @@ -78,8 +109,11 @@ public void testFindDuplicatesBug565462() throws Exception {
director.setFindDuplicates(true);

String className = "java/lang/Class.java";
File srcFile = new File(JavaRuntime.computeVMInstall(configuration).getInstallLocation(), "lib/src.zip");
assertTrue(srcFile.getAbsolutePath() + " doesn't exist", srcFile.isFile());
Object[] foundElements = director.findSourceElements(className);
assertEquals("Expected only 1 match for class " + className + ", but found: " + Arrays.toString(foundElements), 1, foundElements.length);
assertEquals("Expected only 1 match for class " + className + " in " + JavaRuntime.computeVMInstall(configuration).getInstallLocation() + " but found: " + Arrays.toString(foundElements), 1, foundElements.length);

}

private static void removeModuleAttribute(IJavaProject javaProject) throws JavaModelException {
Expand Down
2 changes: 1 addition & 1 deletion org.eclipse.jdt.debug.ui/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.jdt.debug.ui; singleton:=true
Bundle-Version: 3.13.0.qualifier
Bundle-Version: 3.13.100.qualifier
Bundle-Activator: org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Expand Down
2 changes: 1 addition & 1 deletion org.eclipse.jdt.debug.ui/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
</parent>
<groupId>org.eclipse.jdt</groupId>
<artifactId>org.eclipse.jdt.debug.ui</artifactId>
<version>3.13.0-SNAPSHOT</version>
<version>3.13.100-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
<properties>
<code.ignoredWarnings>-warn:+resource,-deprecation,unavoidableGenericProblems</code.ignoredWarnings>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,4 +210,6 @@ public class JREMessages extends NLS {
public static String LibraryLabelProvider_0;

public static String VMDetailsDialog_0;

public static String detectJREsAtStartup;
}
Original file line number Diff line number Diff line change
Expand Up @@ -142,3 +142,5 @@ VMExternalAnnsBlock_1=External annotations:
VMExternalAnnsBlock_2=(none)
VMExternalAnnsBlock_3=E&xternal annotations...
VMExternalAnnsBlock_4=Select to add the external annotations file or directory to the selected library

detectJREsAtStartup=Detect available JVM installations at startup
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.eclipse.jdt.debug.ui.IJavaDebugUIConstants;
import org.eclipse.jdt.internal.debug.ui.IJavaDebugHelpContextIds;
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
import org.eclipse.jdt.internal.launching.LaunchingPlugin;
import org.eclipse.jdt.internal.launching.StandardVMType;
import org.eclipse.jdt.launching.AbstractVMInstall;
import org.eclipse.jdt.launching.IVMInstall;
Expand All @@ -49,13 +50,15 @@
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Link;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;
import org.eclipse.ui.preferences.ScopedPreferenceStore;

/**
* The Installed JREs preference page.
Expand All @@ -75,6 +78,8 @@ public class JREsPreferencePage extends PreferencePage implements IWorkbenchPref
private InstalledJREsBlock fJREBlock;
private Link fCompliance;

private Button detectAtStartupCheckbox;

/**
* Constructor
*/
Expand All @@ -87,6 +92,8 @@ public JREsPreferencePage() {
*/
@Override
public void init(IWorkbench workbench) {
setPreferenceStore(new ScopedPreferenceStore(InstanceScope.INSTANCE,
mickaelistria marked this conversation as resolved.
Show resolved Hide resolved
LaunchingPlugin.getDefault().getBundle().getSymbolicName()));
}

/**
Expand Down Expand Up @@ -124,6 +131,9 @@ protected Control createContents(Composite ancestor) {
SWTFactory.createWrapLabel(ancestor, JREMessages.JREsPreferencePage_2, 1, 300);
SWTFactory.createVerticalSpacer(ancestor, 1);

detectAtStartupCheckbox = SWTFactory.createCheckButton(ancestor, JREMessages.detectJREsAtStartup, null, getPreferenceStore().getBoolean(LaunchingPlugin.PREF_DETECT_VMS_AT_STARTUP), 1);
SWTFactory.createVerticalSpacer(ancestor, 1);

fJREBlock = new InstalledJREsBlock();
fJREBlock.createControl(ancestor);
Control control = fJREBlock.getControl();
Expand Down Expand Up @@ -167,6 +177,7 @@ public void selectionChanged(SelectionChangedEvent event) {
}
}
});

applyDialogFont(ancestor);
return ancestor;
}
Expand Down Expand Up @@ -295,6 +306,7 @@ public void run() {
}
}
});
getPreferenceStore().setValue(LaunchingPlugin.PREF_DETECT_VMS_AT_STARTUP, detectAtStartupCheckbox.getSelection());

if(canceled[0]) {
return false;
Expand Down
2 changes: 1 addition & 1 deletion org.eclipse.jdt.debug/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.jdt.debug; singleton:=true
Bundle-Version: 3.21.0.qualifier
Bundle-Version: 3.21.100.qualifier
Bundle-ClassPath: jdimodel.jar
Bundle-Activator: org.eclipse.jdt.internal.debug.core.JDIDebugPlugin
Bundle-Vendor: %providerName
Expand Down
2 changes: 1 addition & 1 deletion org.eclipse.jdt.debug/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@
</parent>
<groupId>org.eclipse.jdt</groupId>
<artifactId>org.eclipse.jdt.debug</artifactId>
<version>3.21.0-SNAPSHOT</version>
<version>3.21.100-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
2 changes: 1 addition & 1 deletion org.eclipse.jdt.launching/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.jdt.launching; singleton:=true
Bundle-Version: 3.20.0.qualifier
Bundle-Version: 3.20.100.qualifier
Bundle-Activator: org.eclipse.jdt.internal.launching.LaunchingPlugin
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/*******************************************************************************
* Copyright (c) 2023 Red Hat, Inc. and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.jdt.internal.launching;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.IVMInstall2;
import org.eclipse.jdt.launching.IVMInstallType;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.launching.VMStandin;

mickaelistria marked this conversation as resolved.
Show resolved Hide resolved
/**
* Lookup for VMs installed in standard or usual locations; and add the existing ones that
* are not yet known by JDT to the VM registry (usually visible in the "Installed JREs"
* preference page)
*/
class DetectVMInstallationsJob extends Job {

private static final Object FAMILY = DetectVMInstallationsJob.class;

private final StandardVMType standardType;

DetectVMInstallationsJob() {
super(LaunchingMessages.lookupInstalledJVMs);
this.standardType = (StandardVMType)JavaRuntime.getVMInstallType(StandardVMType.ID_STANDARD_VM_TYPE);
}

@Override
protected IStatus run(IProgressMonitor monitor) {
mickaelistria marked this conversation as resolved.
Show resolved Hide resolved
Collection<File> candidates = computeCandidateVMs();
if (monitor.isCanceled()) {
return Status.CANCEL_STATUS;
}
Set<File> knownVMs = knownVMs();
candidates.removeIf(knownVMs::contains);
monitor.beginTask(LaunchingMessages.lookupInstalledJVMs, candidates.size());
for (File f : candidates) {
if (monitor.isCanceled()) {
return Status.CANCEL_STATUS;
}
SubMonitor subMon = SubMonitor.convert(monitor, f.getAbsolutePath(), 1);
VMStandin workingCopy = new VMStandin(standardType, f.getAbsolutePath());
workingCopy.setInstallLocation(f);
String name = f.getName();
int i = 1;
while (isDuplicateName(name)) {
name = f.getName() + '(' + i++ + ')';
}
workingCopy.setName(name);
IVMInstall install = workingCopy.convertToRealVM();
if (!(install instanceof IVMInstall2 vm && vm.getJavaVersion() != null)) {
// worksaround: such VMs may cause issue later
// https://github.com/eclipse-jdt/eclipse.jdt.debug/issues/248
standardType.disposeVMInstall(install.getId());
}
subMon.done();
}
return Status.OK_STATUS;
}

private boolean isDuplicateName(String name) {
return Stream.of(JavaRuntime.getVMInstallTypes()) //
.flatMap(vmType -> Arrays.stream(vmType.getVMInstalls())) //
.map(IVMInstall::getName) //
.anyMatch(name::equals);
}

private Collection<File> computeCandidateVMs() {
// parent directories containing a collection of VM installations
Collection<File> rootDirectories = new HashSet<>();
if (!Platform.OS_WIN32.equals(Platform.getOS())) {
jjohnstn marked this conversation as resolved.
Show resolved Hide resolved
rootDirectories.add(new File("/usr/lib/jvm")); //$NON-NLS-1$
}
if (Platform.OS_MACOSX.equals(Platform.getOS())) {
rootDirectories.add(new File("/Library/Java/JavaVirtualMachines")); //$NON-NLS-1$
}
rootDirectories.add(new File(System.getProperty("user.home"), ".sdkman/candidates/java")); //$NON-NLS-1$ //$NON-NLS-2$
mickaelistria marked this conversation as resolved.
Show resolved Hide resolved

Set<File> directories = rootDirectories.stream().filter(File::isDirectory)
.map(dir -> dir.listFiles(File::isDirectory))
.flatMap(Arrays::stream)
.filter(Objects::nonNull)
.collect(Collectors.toSet());

// particular VM installations
String javaHome = System.getenv("JAVA_HOME"); //$NON-NLS-1$
if (javaHome != null) {
directories.add(new File(javaHome));
}
String jdkHome = System.getenv("JDK_HOME"); //$NON-NLS-1$
if (jdkHome != null) {
directories.add(new File(jdkHome));
}
// other common/standard lookup strategies can be added here

return directories.stream()
.filter(Objects::nonNull)
.filter(File::isDirectory)
.map(t -> {
try {
return t.getCanonicalFile();
} catch (IOException e) {
return null;
}
}).filter(Objects::nonNull)
.filter(location -> standardType.validateInstallLocation(location).isOK())
.collect(Collectors.toCollection(HashSet::new));
}

private static Set<File> knownVMs() {
return Stream.of(JavaRuntime.getVMInstallTypes())
.map(IVMInstallType::getVMInstalls)
.flatMap(Arrays::stream)
.map(IVMInstall::getInstallLocation)
.filter(Objects::nonNull)
.map(t -> {
try {
return t.getCanonicalFile();
} catch (IOException e) {
return null;
}
}).filter(Objects::nonNull)
.collect(Collectors.toSet());
}

@Override
public boolean belongsTo(Object family) {
return family.equals(FAMILY);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -249,4 +249,8 @@ public class LaunchingMessages extends NLS {

public static String RunnerBootpathPError;

public static String lookupInstalledJVMs;

public static String configuringJVM;

}
Loading