/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package org.dlect.helper; import com.google.common.base.Optional; import com.google.common.io.Files; import java.io.File; import java.io.IOException; import javax.annotation.Nonnull; import org.dlect.helpers.StringUtil; import org.dlect.update.UpdateLogger; /** * * @author lee */ public class JavaHelper { private final ExecutableWrapper executableWrapper; public static File getJarFile() { String encodedPath = JavaHelper.class.getProtectionDomain().getCodeSource().getLocation().getPath(); String path = encodedPath.replace("+", "%2B"); String decoded = StringUtil.decodeURL(path); return new File(decoded); } public JavaHelper() { this(new ExecutableWrapperImpl()); } public JavaHelper(ExecutableWrapper executableWrapper) { this.executableWrapper = executableWrapper; } @Nonnull public Optional<String> getJavaExecutable() { Optional<String> java = checkJava(); if (!java.isPresent()) { return searchForJava(); } return java; } @Nonnull protected Optional<String> checkJava() { try { Process exec = executableWrapper.exec(false, "java", "-version"); // This will throw an IOException if it can't find `java`. exec.destroy(); // So we can just destroy it, We don't care about the output or // the exit code, and during testing it took some time to exit. // So just destroying it will save time and memory. return Optional.of("java"); } catch (IOException ex) { UpdateLogger.LOGGER.error("Failed to create process from plain java instance!", ex); return Optional.absent(); } } @Nonnull protected Optional<String> searchForJava() { String p = System.getProperty("java.home", null); // Use the `java.home` property. It points to the folder that the `bin` // directory resides. // However it could be null, so check that. if (p != null) { p = Files.simplifyPath(p + "/bin/java"); // Move into the bin directory and call java. // Could call javaw if on windows but it would make no difference, // as this application controls the terminal/command line. if (System.getProperty("os.name", "Unknown").contains("Windows")) { // Add the `exe` extension on windows. p += ".exe"; } try { // Don't need the quotes around the command, as the exec // command calls it directly instead of through the terminal. Process exec = executableWrapper.exec(false, p, "-version"); // If we get here, then it must have succedded, so destroy the // process and exit. exec.destroy(); return Optional.of(p); } catch (IOException ex) { UpdateLogger.LOGGER.error("Failed to create process from `java.home` java instance!", ex); } } return Optional.absent(); } }