Copyright (c) 2010, 2013 IBM Corporation 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 Contributors: IBM Corporation - initial API and implementation
/******************************************************************************* * Copyright (c) 2010, 2013 IBM Corporation 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 * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/
package org.eclipse.jdt.internal.launching; import java.io.ByteArrayInputStream; import java.io.File; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubMonitor; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunchManager; import org.eclipse.debug.core.Launch; import org.eclipse.debug.core.model.IProcess; import org.eclipse.debug.core.model.IStreamsProxy; import org.eclipse.jdt.launching.AbstractVMInstallType; import org.eclipse.jdt.launching.IVMInstallType; import org.eclipse.jdt.launching.JavaRuntime; import org.eclipse.jdt.launching.VMStandin; import org.eclipse.osgi.util.NLS;
Searches for installed JREs on the Mac.
/** * Searches for installed JREs on the Mac. */
public class MacInstalledJREs {
The executable for 'java_home'
/** The executable for 'java_home' */
private static final String JAVA_HOME_PLIST = "/usr/libexec/java_home"; //$NON-NLS-1$
The plist attribute describing the JRE home directory
/** The plist attribute describing the JRE home directory */
private static final String PLIST_JVM_HOME_PATH = "JVMHomePath"; //$NON-NLS-1$
The plist attribute describing the JRE name
/** The plist attribute describing the JRE name */
private static final String PLIST_JVM_NAME = "JVMName"; //$NON-NLS-1$
The plist attribute describing the JRE version
/** The plist attribute describing the JRE version */
private static final String PLIST_JVM_VERSION = "JVMVersion"; //$NON-NLS-1$
The plist attribute describing the bundle id of the VM
Since:3.8
/** * The plist attribute describing the bundle id of the VM * @since 3.8 */
private static final String PLIST_JVM_BUNDLE_ID = "JVMBundleID"; //$NON-NLS-1$ public static final VMStandin[] NO_VMS = new VMStandin[0];
Custom stand-in that allows us to provide a version
Since:3.7.0
/** * Custom stand-in that allows us to provide a version * @since 3.7.0 */
public static class MacVMStandin extends VMStandin { String version = null; public MacVMStandin(IVMInstallType type, File location, String name, String version, String id) { super(type, id); setInstallLocation(location); setName(name); this.version = version; } @Override public String getJavaVersion() { return version; } }
Parses the XML output produced from "java_home -X" (see bug 325777), and return a collection of descriptions of JRE installations.
Params:
Throws:
  • CoreException – if unable to parse the output or the executable does not exist
Returns:array of VMStandins installed in the OS
/** * Parses the XML output produced from "java_home -X" (see bug 325777), and return a collection * of descriptions of JRE installations. * * @param monitor the {@link IProgressMonitor} or <code>null</code> * @return array of {@link VMStandin}s installed in the OS * @exception CoreException if unable to parse the output or the executable does not exist */
public static VMStandin[] getInstalledJREs(IProgressMonitor monitor) throws CoreException { SubMonitor smonitor = SubMonitor.convert(monitor); try { // locate the "java_home" executable File java_home = new File(JAVA_HOME_PLIST); if (!java_home.exists()) { throw new CoreException(new Status(IStatus.WARNING, LaunchingPlugin.getUniqueIdentifier(), "The java_home executable does not exist")); //$NON-NLS-1$ } String[] cmdLine = new String[] {JAVA_HOME_PLIST, "-X"}; //$NON-NLS-1$ Process p = null; try { p = DebugPlugin.exec(cmdLine, null); IProcess process = DebugPlugin.newProcess(new Launch(null, ILaunchManager.RUN_MODE, null), p, "JRE Install Detection"); //$NON-NLS-1$ for (int i= 0; i < 600; i++) { // Wait no more than 30 seconds (600 * 50 milliseconds) if (process.isTerminated()) { break; } try { Thread.sleep(50); } catch (InterruptedException e) { // do nothing } } return parseJREInfo(process, monitor); } finally { if (p != null) { p.destroy(); } } } finally { if(!smonitor.isCanceled()) { smonitor.done(); } } }
Parses the output from 'java_home -X'.
Params:
  • process – process with output from 'java_home -X'
  • the – IProgressMonitor or null
Throws:
Returns:array JRE descriptions installed in the OS
/** * Parses the output from 'java_home -X'. * * @param process process with output from 'java_home -X' * @param the {@link IProgressMonitor} or <code>null</code> * @return array JRE descriptions installed in the OS * @exception CoreException if unable to parse the output */
private static VMStandin[] parseJREInfo(IProcess process, IProgressMonitor monitor) throws CoreException { IStreamsProxy streamsProxy = process.getStreamsProxy(); String text = null; if (streamsProxy != null) { text = streamsProxy.getOutputStreamMonitor().getContents(); } if (text != null && text.length() > 0) { ByteArrayInputStream stream = new ByteArrayInputStream(text.getBytes()); return parseJREInfo(stream, monitor); } return NO_VMS; }
Parse JREDescriptors from the given input stream. The stream is expected to be in the XML properties format.
Params:
Returns:the array of VMStandins or an empty array never null
Since:3.8
/** * Parse {@link JREDescriptor}s from the given input stream. The stream is expected to be in the * XML properties format. * * @param monitor the {@link IProgressMonitor} or <code>null</code> * @param stream * @return the array of {@link VMStandin}s or an empty array never <code>null</code> * @since 3.8 */
public static VMStandin[] parseJREInfo(InputStream stream, IProgressMonitor monitor) { SubMonitor smonitor = SubMonitor.convert(monitor, LaunchingMessages.MacInstalledJREs_0, 10); try { Object result = new PListParser().parse(stream); if (result instanceof Object[]) { Object[] maps = (Object[]) result; smonitor.setWorkRemaining(maps.length); List<VMStandin> jres= new ArrayList<>(); AbstractVMInstallType mactype = (AbstractVMInstallType) JavaRuntime.getVMInstallType("org.eclipse.jdt.internal.launching.macosx.MacOSXType"); //$NON-NLS-1$ if(mactype != null) { for (int i = 0; i < maps.length; i++) { if(smonitor.isCanceled()) { ///stop processing and return what we found return jres.toArray(new VMStandin[jres.size()]); } Object object = maps[i]; if (object instanceof Map) { Map<?, ?> map = (Map<?, ?>) object; Object home = map.get(PLIST_JVM_HOME_PATH); Object name = map.get(PLIST_JVM_NAME); Object version = map.get(PLIST_JVM_VERSION); if (home instanceof String && name instanceof String && version instanceof String) { smonitor.setTaskName(NLS.bind(LaunchingMessages.MacInstalledJREs_1, new String[] {(String) name, (String) version})); String ver = (String) version; File loc = new File((String)home); //10.8.2+ can have more than one of the same VM, which will have the same name //augment it with the version to make it easier to distinguish StringBuilder namebuff = new StringBuilder(name.toString()); namebuff.append(" [").append(ver).append("]"); //$NON-NLS-1$//$NON-NLS-2$ MacVMStandin vm = new MacVMStandin(mactype, loc, namebuff.toString(), ver, computeId(map, ver)); vm.setJavadocLocation(mactype.getDefaultJavadocLocation(loc)); vm.setLibraryLocations(mactype.getDefaultLibraryLocations(loc)); vm.setVMArgs(mactype.getDefaultVMArguments(loc)); if (!jres.contains(vm)) { // remove duplicates jres.add(vm); } } } smonitor.worked(1); } } return jres.toArray(new VMStandin[jres.size()]); } } catch (CoreException ce) { LaunchingPlugin.log(ce); } finally { smonitor.done(); } return NO_VMS; }
Tries to compute the descriptor id using the PLIST_JVM_BUNDLE_ID. If that is not defined we fall back to using the version.
Params:
  • map – the map to look up the VM bundle version in
  • version – the current version - fall-back for no VM bundle id defined
Returns:the id to use for the JREDescriptor
Since:3.8
/** * Tries to compute the descriptor id using the {@link #PLIST_JVM_BUNDLE_ID}. If that is not defined * we fall back to using the version. * @param map the map to look up the VM bundle version in * @param version the current version - fall-back for no VM bundle id defined * @return the id to use for the {@link JREDescriptor} * @since 3.8 */
static String computeId(Map<?, ?> map, String version) { Object o = map.get(PLIST_JVM_BUNDLE_ID); if(o instanceof String) { return (String) o; } return version; } }