Refactor Java lookup
This commit is contained in:
@@ -238,7 +238,7 @@ public final class LauncherHelper {
|
|||||||
|
|
||||||
// Game later than 1.7.2 accepts Java 8.
|
// Game later than 1.7.2 accepts Java 8.
|
||||||
if (!flag && java.getParsedVersion() < JavaVersion.JAVA_8 && gameVersion.compareTo(VersionNumber.asVersion("1.7.2")) > 0) {
|
if (!flag && java.getParsedVersion() < JavaVersion.JAVA_8 && gameVersion.compareTo(VersionNumber.asVersion("1.7.2")) > 0) {
|
||||||
Optional<JavaVersion> java8 = JavaVersion.getJREs().stream()
|
Optional<JavaVersion> java8 = JavaVersion.getJavas().stream()
|
||||||
.filter(javaVersion -> javaVersion.getParsedVersion() >= JavaVersion.JAVA_8)
|
.filter(javaVersion -> javaVersion.getParsedVersion() >= JavaVersion.JAVA_8)
|
||||||
.max(Comparator.comparing(JavaVersion::getVersionNumber));
|
.max(Comparator.comparing(JavaVersion::getVersionNumber));
|
||||||
if (java8.isPresent()) {
|
if (java8.isPresent()) {
|
||||||
@@ -263,7 +263,7 @@ public final class LauncherHelper {
|
|||||||
&& version.getLibraries().stream()
|
&& version.getLibraries().stream()
|
||||||
.filter(library -> "launchwrapper".equals(library.getArtifactId()))
|
.filter(library -> "launchwrapper".equals(library.getArtifactId()))
|
||||||
.anyMatch(library -> VersionNumber.asVersion(library.getVersion()).compareTo(VersionNumber.asVersion("1.13")) < 0)) {
|
.anyMatch(library -> VersionNumber.asVersion(library.getVersion()).compareTo(VersionNumber.asVersion("1.13")) < 0)) {
|
||||||
Optional<JavaVersion> java8 = JavaVersion.getJREs().stream().filter(javaVersion -> javaVersion.getParsedVersion() == JavaVersion.JAVA_8).findAny();
|
Optional<JavaVersion> java8 = JavaVersion.getJavas().stream().filter(javaVersion -> javaVersion.getParsedVersion() == JavaVersion.JAVA_8).findAny();
|
||||||
if (java8.isPresent()) {
|
if (java8.isPresent()) {
|
||||||
java8required = true;
|
java8required = true;
|
||||||
setting.setJavaVersion(java8.get());
|
setting.setJavaVersion(java8.get());
|
||||||
@@ -276,7 +276,7 @@ public final class LauncherHelper {
|
|||||||
// Minecraft 1.13 may crash when generating world on Java 8 earlier than 1.8.0_51
|
// Minecraft 1.13 may crash when generating world on Java 8 earlier than 1.8.0_51
|
||||||
VersionNumber JAVA_8 = VersionNumber.asVersion("1.8.0.51");
|
VersionNumber JAVA_8 = VersionNumber.asVersion("1.8.0.51");
|
||||||
if (!flag && gameVersion.compareTo(VersionNumber.asVersion("1.13")) >= 0 && java.getParsedVersion() == JavaVersion.JAVA_8 && java.getVersionNumber().compareTo(JAVA_8) < 0) {
|
if (!flag && gameVersion.compareTo(VersionNumber.asVersion("1.13")) >= 0 && java.getParsedVersion() == JavaVersion.JAVA_8 && java.getVersionNumber().compareTo(JAVA_8) < 0) {
|
||||||
Optional<JavaVersion> java8 = JavaVersion.getJREs().stream()
|
Optional<JavaVersion> java8 = JavaVersion.getJavas().stream()
|
||||||
.filter(javaVersion -> javaVersion.getVersionNumber().compareTo(JAVA_8) >= 0)
|
.filter(javaVersion -> javaVersion.getVersionNumber().compareTo(JAVA_8) >= 0)
|
||||||
.max(Comparator.comparing(JavaVersion::getVersionNumber));
|
.max(Comparator.comparing(JavaVersion::getVersionNumber));
|
||||||
if (java8.isPresent()) {
|
if (java8.isPresent()) {
|
||||||
@@ -293,7 +293,7 @@ public final class LauncherHelper {
|
|||||||
final JavaVersion java32 = java;
|
final JavaVersion java32 = java;
|
||||||
|
|
||||||
// First find if same java version but whose platform is 64-bit installed.
|
// First find if same java version but whose platform is 64-bit installed.
|
||||||
Optional<JavaVersion> java64 = JavaVersion.getJREs().stream()
|
Optional<JavaVersion> java64 = JavaVersion.getJavas().stream()
|
||||||
.filter(javaVersion -> javaVersion.getPlatform() == org.jackhuang.hmcl.util.platform.Platform.PLATFORM)
|
.filter(javaVersion -> javaVersion.getPlatform() == org.jackhuang.hmcl.util.platform.Platform.PLATFORM)
|
||||||
.filter(javaVersion -> javaVersion.getParsedVersion() == java32.getParsedVersion())
|
.filter(javaVersion -> javaVersion.getParsedVersion() == java32.getParsedVersion())
|
||||||
.max(Comparator.comparing(JavaVersion::getVersionNumber));
|
.max(Comparator.comparing(JavaVersion::getVersionNumber));
|
||||||
@@ -302,7 +302,7 @@ public final class LauncherHelper {
|
|||||||
final boolean java8requiredFinal = java8required, newJavaRequiredFinal = newJavaRequired;
|
final boolean java8requiredFinal = java8required, newJavaRequiredFinal = newJavaRequired;
|
||||||
|
|
||||||
// Then find if other java version which satisfies requirements installed.
|
// Then find if other java version which satisfies requirements installed.
|
||||||
java64 = JavaVersion.getJREs().stream()
|
java64 = JavaVersion.getJavas().stream()
|
||||||
.filter(javaVersion -> javaVersion.getPlatform() == org.jackhuang.hmcl.util.platform.Platform.PLATFORM)
|
.filter(javaVersion -> javaVersion.getPlatform() == org.jackhuang.hmcl.util.platform.Platform.PLATFORM)
|
||||||
.filter(javaVersion -> {
|
.filter(javaVersion -> {
|
||||||
if (java8requiredFinal) return javaVersion.getParsedVersion() == JavaVersion.JAVA_8;
|
if (java8requiredFinal) return javaVersion.getParsedVersion() == JavaVersion.JAVA_8;
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import org.jackhuang.hmcl.util.platform.OperatingSystem;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
import java.nio.file.Paths;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@@ -455,12 +456,12 @@ public final class VersionSetting {
|
|||||||
if ("Default".equals(getJava())) return JavaVersion.fromCurrentEnvironment();
|
if ("Default".equals(getJava())) return JavaVersion.fromCurrentEnvironment();
|
||||||
else if (isUsesCustomJavaDir()) {
|
else if (isUsesCustomJavaDir()) {
|
||||||
try {
|
try {
|
||||||
return JavaVersion.fromExecutable(new File(getJavaDir()));
|
return JavaVersion.fromExecutable(Paths.get(getJavaDir()));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
return null; // Custom Java Directory not found,
|
return null; // Custom Java Directory not found,
|
||||||
}
|
}
|
||||||
} else if (StringUtils.isNotBlank(getJava())) {
|
} else if (StringUtils.isNotBlank(getJava())) {
|
||||||
List<JavaVersion> matchedJava = JavaVersion.getJREs().stream()
|
List<JavaVersion> matchedJava = JavaVersion.getJavas().stream()
|
||||||
.filter(java -> java.getVersion().equals(getJava()))
|
.filter(java -> java.getVersion().equals(getJava()))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
if (matchedJava.isEmpty()) {
|
if (matchedJava.isEmpty()) {
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ import org.jackhuang.hmcl.util.platform.OperatingSystem;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -106,11 +107,11 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag
|
|||||||
|
|
||||||
FXUtils.smoothScrolling(scroll);
|
FXUtils.smoothScrolling(scroll);
|
||||||
|
|
||||||
Task.of(variables -> variables.set("list", JavaVersion.getJREs()))
|
Task.of(variables -> variables.set("list", JavaVersion.getJavas()))
|
||||||
.subscribe(Schedulers.javafx(), variables -> {
|
.subscribe(Schedulers.javafx(), variables -> {
|
||||||
javaItem.loadChildren(
|
javaItem.loadChildren(
|
||||||
(variables.<List<JavaVersion>>get("list")).stream()
|
(variables.<List<JavaVersion>>get("list")).stream()
|
||||||
.map(javaVersion -> javaItem.createChildren(javaVersion.getVersion() + i18n("settings.game.java_directory.bit", javaVersion.getPlatform().getBit()), javaVersion.getBinary().getAbsolutePath(), javaVersion))
|
.map(javaVersion -> javaItem.createChildren(javaVersion.getVersion() + i18n("settings.game.java_directory.bit", javaVersion.getPlatform().getBit()), javaVersion.getBinary().toString(), javaVersion))
|
||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
javaItemsLoaded = true;
|
javaItemsLoaded = true;
|
||||||
initializeSelectedJava();
|
initializeSelectedJava();
|
||||||
@@ -259,7 +260,7 @@ public final class VersionSettingsPage extends StackPane implements DecoratorPag
|
|||||||
Task.of(variables -> variables.set("java", versionSetting.getJavaVersion()))
|
Task.of(variables -> variables.set("java", versionSetting.getJavaVersion()))
|
||||||
.subscribe(Task.of(Schedulers.javafx(),
|
.subscribe(Task.of(Schedulers.javafx(),
|
||||||
variables -> javaItem.setSubtitle(variables.<JavaVersion>getOptional("java")
|
variables -> javaItem.setSubtitle(variables.<JavaVersion>getOptional("java")
|
||||||
.map(JavaVersion::getBinary).map(File::getAbsolutePath).orElse("Invalid Java Directory"))));
|
.map(JavaVersion::getBinary).map(Path::toString).orElse("Invalid Java Directory"))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ public final class UpdateHandler {
|
|||||||
|
|
||||||
private static void startJava(Path jar, String... appArgs) throws IOException {
|
private static void startJava(Path jar, String... appArgs) throws IOException {
|
||||||
List<String> commandline = new ArrayList<>();
|
List<String> commandline = new ArrayList<>();
|
||||||
commandline.add(JavaVersion.fromCurrentEnvironment().getBinary().getAbsolutePath());
|
commandline.add(JavaVersion.fromCurrentEnvironment().getBinary().toString());
|
||||||
commandline.add("-jar");
|
commandline.add("-jar");
|
||||||
commandline.add(jar.toAbsolutePath().toString());
|
commandline.add(jar.toAbsolutePath().toString());
|
||||||
for (String arg : appArgs) {
|
for (String arg : appArgs) {
|
||||||
|
|||||||
@@ -17,27 +17,24 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.util.platform;
|
package org.jackhuang.hmcl.util.platform;
|
||||||
|
|
||||||
|
import static java.util.Collections.unmodifiableList;
|
||||||
|
import static java.util.stream.Collectors.toList;
|
||||||
|
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.LinkOption;
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.jackhuang.hmcl.util.Lang;
|
|
||||||
import org.jackhuang.hmcl.util.Logging;
|
|
||||||
import org.jackhuang.hmcl.util.StringUtils;
|
import org.jackhuang.hmcl.util.StringUtils;
|
||||||
import org.jackhuang.hmcl.util.versioning.VersionNumber;
|
import org.jackhuang.hmcl.util.versioning.VersionNumber;
|
||||||
|
|
||||||
@@ -48,19 +45,19 @@ import org.jackhuang.hmcl.util.versioning.VersionNumber;
|
|||||||
*/
|
*/
|
||||||
public final class JavaVersion {
|
public final class JavaVersion {
|
||||||
|
|
||||||
private final File binary;
|
private final Path binary;
|
||||||
private final String longVersion;
|
private final String longVersion;
|
||||||
private final Platform platform;
|
private final Platform platform;
|
||||||
private final int version;
|
private final int version;
|
||||||
|
|
||||||
public JavaVersion(File binary, String longVersion, Platform platform) {
|
public JavaVersion(Path binary, String longVersion, Platform platform) {
|
||||||
this.binary = binary;
|
this.binary = binary;
|
||||||
this.longVersion = longVersion;
|
this.longVersion = longVersion;
|
||||||
this.platform = platform;
|
this.platform = platform;
|
||||||
version = parseVersion(longVersion);
|
version = parseVersion(longVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
public File getBinary() {
|
public Path getBinary() {
|
||||||
return binary;
|
return binary;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,15 +111,18 @@ public final class JavaVersion {
|
|||||||
return UNKNOWN;
|
return UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JavaVersion fromExecutable(File executable) throws IOException {
|
public static JavaVersion fromExecutable(Path executable) throws IOException {
|
||||||
Platform platform = Platform.BIT_32;
|
Platform platform = Platform.BIT_32;
|
||||||
String version = null;
|
String version = null;
|
||||||
|
|
||||||
// javaw is only used on windows
|
// javaw is only used on windows
|
||||||
if ("javaw.exe".equalsIgnoreCase(executable.getName()))
|
if ("javaw.exe".equalsIgnoreCase(executable.getFileName().toString())) {
|
||||||
executable = new File(executable.getAbsoluteFile().getParentFile(), "java.exe");
|
executable = executable.resolveSibling("java.exe");
|
||||||
|
}
|
||||||
|
|
||||||
Process process = new ProcessBuilder(executable.getAbsolutePath(), "-version").start();
|
executable = executable.toRealPath();
|
||||||
|
|
||||||
|
Process process = new ProcessBuilder(executable.toString(), "-version").start();
|
||||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream()))) {
|
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream()))) {
|
||||||
for (String line; (line = reader.readLine()) != null;) {
|
for (String line; (line = reader.readLine()) != null;) {
|
||||||
Matcher m = REGEX.matcher(line);
|
Matcher m = REGEX.matcher(line);
|
||||||
@@ -134,7 +134,7 @@ public final class JavaVersion {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (version == null)
|
if (version == null)
|
||||||
throw new IOException("No matched Java version.");
|
throw new IOException("No Java version is matched");
|
||||||
|
|
||||||
if (parseVersion(version) == UNKNOWN)
|
if (parseVersion(version) == UNKNOWN)
|
||||||
throw new IOException("Unrecognized Java version " + version);
|
throw new IOException("Unrecognized Java version " + version);
|
||||||
@@ -142,181 +142,174 @@ public final class JavaVersion {
|
|||||||
return new JavaVersion(executable, version, platform);
|
return new JavaVersion(executable, version, platform);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JavaVersion fromJavaHome(File home) throws IOException {
|
private static Path getExecutable(Path javaHome) {
|
||||||
return fromExecutable(getExecutable(home));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static File getExecutable(File javaHome) {
|
|
||||||
if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS) {
|
if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS) {
|
||||||
return new File(javaHome, "bin/java.exe");
|
return javaHome.resolve("bin").resolve("java.exe");
|
||||||
} else {
|
} else {
|
||||||
return new File(javaHome, "bin/java");
|
return javaHome.resolve("bin").resolve("java");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JavaVersion fromCurrentEnvironment() {
|
public static JavaVersion fromCurrentEnvironment() {
|
||||||
return THIS_JAVA;
|
return CURRENT_JAVA;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final JavaVersion THIS_JAVA = new JavaVersion(
|
public static final JavaVersion CURRENT_JAVA;
|
||||||
getExecutable(new File(System.getProperty("java.home"))),
|
|
||||||
System.getProperty("java.version"),
|
static {
|
||||||
Platform.PLATFORM
|
Path currentExecutable = getExecutable(Paths.get(System.getProperty("java.home")));
|
||||||
);
|
try {
|
||||||
|
currentExecutable = currentExecutable.toRealPath();
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.log(Level.WARNING, "Failed to resolve current Java path: " + currentExecutable, e);
|
||||||
|
}
|
||||||
|
CURRENT_JAVA = new JavaVersion(
|
||||||
|
currentExecutable,
|
||||||
|
System.getProperty("java.version"),
|
||||||
|
Platform.PLATFORM);
|
||||||
|
}
|
||||||
|
|
||||||
private static List<JavaVersion> JAVAS;
|
private static List<JavaVersion> JAVAS;
|
||||||
private static final CountDownLatch LATCH = new CountDownLatch(1);
|
private static final CountDownLatch LATCH = new CountDownLatch(1);
|
||||||
|
|
||||||
public static List<JavaVersion> getJREs() throws InterruptedException {
|
public static List<JavaVersion> getJavas() throws InterruptedException {
|
||||||
if (JAVAS != null)
|
if (JAVAS != null)
|
||||||
return JAVAS;
|
return JAVAS;
|
||||||
LATCH.await();
|
LATCH.await();
|
||||||
return JAVAS;
|
return JAVAS;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static synchronized void initialize() throws IOException {
|
public static synchronized void initialize() {
|
||||||
if (JAVAS != null)
|
if (JAVAS != null)
|
||||||
throw new IllegalStateException("JavaVersions have already been initialized.");
|
throw new IllegalStateException("JavaVersions have already been initialized.");
|
||||||
|
|
||||||
List<JavaVersion> javaVersions;
|
List<JavaVersion> javaVersions;
|
||||||
switch (OperatingSystem.CURRENT_OS) {
|
|
||||||
case WINDOWS:
|
try {
|
||||||
javaVersions = queryWindows();
|
javaVersions = lookupJavas(searchPotentialJavaHomes());
|
||||||
break;
|
} catch (IOException e) {
|
||||||
case LINUX:
|
LOG.log(Level.WARNING, "Failed to search Java homes", e);
|
||||||
javaVersions = queryLinux();
|
javaVersions = new ArrayList<>();
|
||||||
break;
|
|
||||||
case OSX:
|
|
||||||
javaVersions = queryMacintosh();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
javaVersions = new ArrayList<>();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isCurrentJavaIncluded = false;
|
// insert current java to the list
|
||||||
for (int i = 0; i < javaVersions.size(); i++) {
|
if (!javaVersions.contains(CURRENT_JAVA)) {
|
||||||
if (THIS_JAVA.getBinary().equals(javaVersions.get(i).getBinary())) {
|
javaVersions.add(CURRENT_JAVA);
|
||||||
javaVersions.set(i, THIS_JAVA);
|
|
||||||
isCurrentJavaIncluded = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!isCurrentJavaIncluded) {
|
|
||||||
javaVersions.add(THIS_JAVA);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JAVAS = Collections.unmodifiableList(javaVersions);
|
JAVAS = unmodifiableList(javaVersions);
|
||||||
LATCH.countDown();
|
LATCH.countDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==== Linux ====
|
private static List<JavaVersion> lookupJavas(Stream<Path> javaHomes) {
|
||||||
private static List<JavaVersion> queryLinux() throws IOException {
|
return javaHomes
|
||||||
Path jvmDir = Paths.get("/usr/lib/jvm");
|
.filter(Files::isDirectory)
|
||||||
if (Files.isDirectory(jvmDir)) {
|
.map(JavaVersion::getExecutable)
|
||||||
return Files.list(jvmDir)
|
.filter(Files::isExecutable)
|
||||||
.filter(dir -> Files.isDirectory(dir, LinkOption.NOFOLLOW_LINKS))
|
.flatMap(executable -> { // resolve symbolic links
|
||||||
.map(dir -> dir.resolve("bin/java"))
|
try {
|
||||||
.filter(Files::isExecutable)
|
return Stream.of(executable.toRealPath());
|
||||||
.flatMap(executable -> {
|
} catch (IOException e) {
|
||||||
try {
|
LOG.log(Level.WARNING, "Failed to lookup Java executable at " + executable, e);
|
||||||
return Stream.of(fromExecutable(executable.toFile()));
|
return Stream.empty();
|
||||||
} catch (IOException e) {
|
}
|
||||||
Logging.LOG.log(Level.WARNING, "Couldn't determine java " + executable, e);
|
})
|
||||||
return Stream.empty();
|
.distinct() // remove duplicated javas
|
||||||
}
|
.flatMap(executable -> {
|
||||||
})
|
if (executable.equals(CURRENT_JAVA.getBinary())) {
|
||||||
.collect(Collectors.toList());
|
return Stream.of(CURRENT_JAVA);
|
||||||
} else {
|
}
|
||||||
return Collections.emptyList();
|
try {
|
||||||
}
|
return Stream.of(fromExecutable(executable));
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.log(Level.WARNING, "Failed to determine Java at " + executable, e);
|
||||||
|
return Stream.empty();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect(toList());
|
||||||
}
|
}
|
||||||
// ====
|
|
||||||
|
|
||||||
private static JavaVersion fromJavaHomeQuietly(File home) {
|
private static Stream<Path> searchPotentialJavaHomes() throws IOException {
|
||||||
try {
|
switch (OperatingSystem.CURRENT_OS) {
|
||||||
return fromJavaHome(home);
|
|
||||||
} catch (IOException e) {
|
case WINDOWS:
|
||||||
Logging.LOG.log(Level.WARNING, "Couldn't determine java " + home, e);
|
List<Path> locations = new ArrayList<>();
|
||||||
return null;
|
locations.addAll(queryJavaHomesInRegistryKey("HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Runtime Environment\\"));
|
||||||
|
locations.addAll(queryJavaHomesInRegistryKey("HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\"));
|
||||||
|
locations.addAll(queryJavaHomesInRegistryKey("HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\JRE\\"));
|
||||||
|
locations.addAll(queryJavaHomesInRegistryKey("HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\JDK\\"));
|
||||||
|
return locations.stream();
|
||||||
|
|
||||||
|
case LINUX:
|
||||||
|
Path linuxJvmDir = Paths.get("/usr/lib/jvm");
|
||||||
|
if (Files.isDirectory(linuxJvmDir)) {
|
||||||
|
return Files.list(linuxJvmDir);
|
||||||
|
}
|
||||||
|
return Stream.empty();
|
||||||
|
|
||||||
|
case OSX:
|
||||||
|
Path osxJvmDir = Paths.get("/Library/Java/JavaVirtualMachines");
|
||||||
|
if (Files.isDirectory(osxJvmDir)) {
|
||||||
|
return Files.list(osxJvmDir)
|
||||||
|
.map(dir -> dir.resolve("Contents/Home"));
|
||||||
|
}
|
||||||
|
return Stream.empty();
|
||||||
|
|
||||||
|
default:
|
||||||
|
return Stream.empty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==== OSX ====
|
// ==== Windows Registry Support ====
|
||||||
private static List<JavaVersion> queryMacintosh() {
|
private static List<Path> queryJavaHomesInRegistryKey(String location) throws IOException {
|
||||||
List<JavaVersion> res = new ArrayList<>();
|
List<Path> homes = new ArrayList<>();
|
||||||
|
|
||||||
File currentJRE = new File("/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home");
|
|
||||||
if (currentJRE.exists())
|
|
||||||
res.add(fromJavaHomeQuietly(currentJRE));
|
|
||||||
File[] files = new File("/Library/Java/JavaVirtualMachines/").listFiles();
|
|
||||||
if (files != null)
|
|
||||||
for (File file : files)
|
|
||||||
res.add(fromJavaHomeQuietly(new File(file, "Contents/Home")));
|
|
||||||
|
|
||||||
res.removeIf(Objects::isNull);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
// ====
|
|
||||||
|
|
||||||
// ==== Windows ====
|
|
||||||
private static List<JavaVersion> queryWindows() {
|
|
||||||
List<JavaVersion> res = new ArrayList<>();
|
|
||||||
Lang.ignoringException(() -> res.addAll(queryJavaInRegistryKey("HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Runtime Environment\\")));
|
|
||||||
Lang.ignoringException(() -> res.addAll(queryJavaInRegistryKey("HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\")));
|
|
||||||
Lang.ignoringException(() -> res.addAll(queryJavaInRegistryKey("HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\JRE\\")));
|
|
||||||
Lang.ignoringException(() -> res.addAll(queryJavaInRegistryKey("HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\JDK\\")));
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<JavaVersion> queryJavaInRegistryKey(String location) throws IOException, InterruptedException {
|
|
||||||
List<JavaVersion> res = new ArrayList<>();
|
|
||||||
for (String java : querySubFolders(location)) {
|
for (String java : querySubFolders(location)) {
|
||||||
if (!querySubFolders(java).contains(java + "\\MSI")) continue;
|
if (!querySubFolders(java).contains(java + "\\MSI"))
|
||||||
|
continue;
|
||||||
String home = queryRegisterValue(java, "JavaHome");
|
String home = queryRegisterValue(java, "JavaHome");
|
||||||
if (home != null)
|
if (home != null) {
|
||||||
res.add(fromJavaHomeQuietly(new File(home)));
|
homes.add(Paths.get(home));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return homes;
|
||||||
res.removeIf(Objects::isNull);
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Registry utilities
|
private static List<String> querySubFolders(String location) throws IOException {
|
||||||
private static List<String> querySubFolders(String location) throws IOException, InterruptedException {
|
|
||||||
List<String> res = new ArrayList<>();
|
List<String> res = new ArrayList<>();
|
||||||
String[] cmd = new String[] { "cmd", "/c", "reg", "query", location };
|
|
||||||
Process process = Runtime.getRuntime().exec(cmd);
|
|
||||||
process.waitFor();
|
|
||||||
|
|
||||||
|
Process process = Runtime.getRuntime().exec(new String[] { "cmd", "/c", "reg", "query", location });
|
||||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
|
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
|
||||||
for (String line; (line = reader.readLine()) != null; )
|
for (String line; (line = reader.readLine()) != null;) {
|
||||||
if (line.startsWith(location) && !line.equals(location))
|
if (line.startsWith(location) && !line.equals(location)) {
|
||||||
res.add(line);
|
res.add(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String queryRegisterValue(String location, String name) throws IOException, InterruptedException {
|
private static String queryRegisterValue(String location, String name) throws IOException {
|
||||||
String[] cmd = new String[] { "cmd", "/c", "reg", "query", location, "/v", name };
|
|
||||||
boolean last = false;
|
boolean last = false;
|
||||||
Process process = Runtime.getRuntime().exec(cmd);
|
Process process = Runtime.getRuntime().exec(new String[] { "cmd", "/c", "reg", "query", location, "/v", name });
|
||||||
process.waitFor();
|
|
||||||
|
|
||||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
|
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
|
||||||
for (String line; (line = reader.readLine()) != null; )
|
for (String line; (line = reader.readLine()) != null;) {
|
||||||
if (StringUtils.isNotBlank(line)) {
|
if (StringUtils.isNotBlank(line)) {
|
||||||
if (last && line.trim().startsWith(name)) {
|
if (last && line.trim().startsWith(name)) {
|
||||||
int begins = line.indexOf(name);
|
int begins = line.indexOf(name);
|
||||||
if (begins > 0) {
|
if (begins > 0) {
|
||||||
String s2 = line.substring(begins + name.length());
|
String s2 = line.substring(begins + name.length());
|
||||||
begins = s2.indexOf("REG_SZ");
|
begins = s2.indexOf("REG_SZ");
|
||||||
if (begins > 0)
|
if (begins > 0) {
|
||||||
return s2.substring(begins + "REG_SZ".length()).trim();
|
return s2.substring(begins + "REG_SZ".length()).trim();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (location.equals(line.trim()))
|
if (location.equals(line.trim())) {
|
||||||
last = true;
|
last = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user