/* * SK's Minecraft Launcher * Copyright (C) 2010-2014 Albert Pham <http://www.sk89q.com> and contributors * Please see LICENSE.txt for license information. */ package com.skcraft.launcher.launch; import com.skcraft.launcher.util.Environment; import com.skcraft.launcher.util.Platform; import com.skcraft.launcher.util.WinRegistry; import java.io.File; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * Finds the best Java runtime to use. */ public final class JavaRuntimeFinder { private JavaRuntimeFinder() { } /** * Return the path to the best found JVM location. * * @return the JVM location, or null */ public static File findBestJavaPath() { if (Environment.getInstance().getPlatform() != Platform.WINDOWS) { return null; } List<JREEntry> entries = new ArrayList<JREEntry>(); try { getEntriesFromRegistry(entries, "SOFTWARE\\JavaSoft\\Java Runtime Environment"); getEntriesFromRegistry(entries, "SOFTWARE\\JavaSoft\\Java Development Kit"); } catch (Throwable ignored) { } Collections.sort(entries); if (entries.size() > 0) { return new File(entries.get(0).dir, "bin"); } return null; } private static void getEntriesFromRegistry(List<JREEntry> entries, String basePath) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { List<String> subKeys = WinRegistry.readStringSubKeys(WinRegistry.HKEY_LOCAL_MACHINE, basePath); for (String subKey : subKeys) { JREEntry entry = getEntryFromRegistry(basePath, subKey); if (entry != null) { entries.add(entry); } } } private static JREEntry getEntryFromRegistry(String basePath, String version) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { String regPath = basePath + "\\" + version; String path = WinRegistry.readString(WinRegistry.HKEY_LOCAL_MACHINE, regPath, "JavaHome"); File dir = new File(path); if (dir.exists() && new File(dir, "bin/java.exe").exists()) { JREEntry entry = new JREEntry(); entry.dir = dir; entry.version = version; entry.is64Bit = guessIf64Bit(dir); return entry; } else { return null; } } private static boolean guessIf64Bit(File path) { try { String programFilesX86 = System.getenv("ProgramFiles(x86)"); return programFilesX86 == null || !path.getCanonicalPath().startsWith(new File(programFilesX86).getCanonicalPath()); } catch (IOException ignored) { return false; } } private static class JREEntry implements Comparable<JREEntry> { private File dir; private String version; private boolean is64Bit; @Override public int compareTo(JREEntry o) { if (is64Bit && !o.is64Bit) { return -1; } else if (!is64Bit && o.is64Bit) { return 1; } String[] a = version.split("[\\._]"); String[] b = o.version.split("[\\._]"); int min = Math.min(a.length, b.length); for (int i = 0; i < min; i++) { int first, second; try { first = Integer.parseInt(a[i]); } catch (NumberFormatException e) { return -1; } try { second = Integer.parseInt(b[i]); } catch (NumberFormatException e) { return 1; } if (first > second) { return -1; } else if (first < second) { return 1; } } if (a.length == b.length) { return 0; // Same } return a.length > b.length ? -1 : 1; } } }