Package org.gradle.internal.jvm

Source Code of org.gradle.internal.jvm.Jvm$AppleJvm

/*
* Copyright 2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.gradle.internal.jvm;

import org.gradle.api.JavaVersion;
import org.gradle.api.Nullable;
import org.gradle.internal.SystemProperties;
import org.gradle.internal.UncheckedException;
import org.gradle.internal.os.OperatingSystem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;

public class Jvm implements JavaInfo {
   
    private final static Logger LOGGER = LoggerFactory.getLogger(Jvm.class);
   
    private final OperatingSystem os;
    //supplied java location
    private final File javaBase;
    //discovered java location
    private final File javaHome;
    private final boolean userSupplied;
    private final JavaVersion javaVersion;
    private static final AtomicReference<Jvm> CURRENT = new AtomicReference<Jvm>();

    public static Jvm current() {
        Jvm jvm = CURRENT.get();
        if (jvm == null) {
            CURRENT.compareAndSet(null, create(null));
            jvm = CURRENT.get();
        }
        return jvm;
    }

    static Jvm create(File javaBase) {
        String vendor = System.getProperty("java.vm.vendor");
        if (vendor.toLowerCase().startsWith("apple inc.")) {
            return new AppleJvm(OperatingSystem.current(), javaBase);
        }
        if (vendor.toLowerCase().startsWith("ibm corporation")) {
            return new IbmJvm(OperatingSystem.current(), javaBase);
        }
        return new Jvm(OperatingSystem.current(), javaBase);
    }

    Jvm(OperatingSystem os) {
        this(os, null);
    }

    /**
     * @param os the OS
     * @param suppliedJavaBase initial location to discover from. May be jdk or jre.
     */
    Jvm(OperatingSystem os, File suppliedJavaBase) {
        this.os = os;
        if (suppliedJavaBase == null) {
            //discover based on what's in the sys. property
            try {
                this.javaBase = new File(System.getProperty("java.home")).getCanonicalFile();
            } catch (IOException e) {
                throw new UncheckedException(e);
            }
            this.javaHome = findJavaHome(javaBase);
            this.javaVersion = JavaVersion.current();
            this.userSupplied = false;
        } else {
            //precisely use what the user wants and validate strictly further on
            this.javaBase = suppliedJavaBase;
            this.javaHome = suppliedJavaBase;
            this.userSupplied = true;
            this.javaVersion = null;
        }
    }
   
    /**
     * Creates jvm instance for given java home. Attempts to validate if provided javaHome is a valid jdk or jre location.
     *
     * @param javaHome - location of your jdk or jre (jdk is safer), cannot be null
     * @return jvm for given java home
     *
     * @throws org.gradle.internal.jvm.JavaHomeException when supplied javaHome does not seem to be a valid jdk or jre location
     * @throws IllegalArgumentException when supplied javaHome is not a valid folder
     */
    public static JavaInfo forHome(File javaHome) throws JavaHomeException, IllegalArgumentException {
        if (javaHome == null || !javaHome.isDirectory()) {
            throw new IllegalArgumentException("Supplied javaHome must be a valid directory. You supplied: " + javaHome);
        }
        Jvm jvm = create(javaHome);
        //some validation:
        jvm.getJavaExecutable();
        return jvm;
    }

    @Override
    public String toString() {
        if (userSupplied) {
            return "User-supplied java: " + javaBase;
        }
        return String.format("%s (%s %s)", SystemProperties.getJavaVersion(), System.getProperty("java.vm.vendor"), System.getProperty("java.vm.version"));
    }

    private File findExecutable(String command) {
        File exec = new File(getJavaHome(), "bin/" + command);
        File executable = new File(os.getExecutableName(exec.getAbsolutePath()));
        if (executable.isFile()) {
            return executable;
        }

        if (userSupplied) { //then we want to validate strictly
            throw new JavaHomeException(String.format("The supplied javaHome seems to be invalid."
                    + " I cannot find the %s executable. Tried location: %s", command, executable.getAbsolutePath()));
        }

        File pathExecutable = os.findInPath(command);
        if (pathExecutable != null) {
            LOGGER.info(String.format("Unable to find the '%s' executable using home: %s. We found it on the PATH: %s.",
                    command, getJavaHome(), pathExecutable));
            return pathExecutable;
        }

        LOGGER.warn("Unable to find the '{}' executable. Tried the java home: {} and the PATH."
                + " We will assume the executable can be ran in the current working folder.",
                command, getJavaHome());
        return new File(os.getExecutableName(command));
    }

    /**
     * {@inheritDoc}
     */
    public File getJavaExecutable() throws JavaHomeException {
        return findExecutable("java");
    }

    public File getJavacExecutable() throws JavaHomeException {
        return findExecutable("javac");
    }

    /**
     * {@inheritDoc}
     */
    public File getJavadocExecutable() throws JavaHomeException {
        return findExecutable("javadoc");
    }

    /**
     * {@inheritDoc}
     */
    public File getExecutable(String name) throws JavaHomeException {
        return findExecutable(name);
    }

    /**
     * @return the {@link JavaVersion} information
     */
    public JavaVersion getJavaVersion() {
        return javaVersion;
    }

    /**
     * {@inheritDoc}
     */
    public File getJavaHome() {
        return javaHome;
    }

    private File findJavaHome(File javaBase) {
        File toolsJar = findToolsJar(javaBase);
        if (toolsJar != null) {
            return toolsJar.getParentFile().getParentFile();
        } else if (javaBase.getName().equalsIgnoreCase("jre") && new File(javaBase.getParentFile(), "bin/java").exists()) {
            return javaBase.getParentFile();
        } else {
            return javaBase;
        }
    }

    /**
     * {@inheritDoc}
     */
    public File getRuntimeJar() {
        File runtimeJar = new File(javaBase, "lib/rt.jar");
        if (runtimeJar.exists()) {
            return runtimeJar;
        }
        runtimeJar = new File(javaBase, "jre/lib/rt.jar");
        return runtimeJar.exists() ? runtimeJar : null;
    }

    /**
     * {@inheritDoc}
     */
    public File getToolsJar() {
        return findToolsJar(javaBase);
    }

    /**
     * Locates a stand-alone JRE installation for this JVM. Returns null if not found.
     */
    @Nullable
    public Jre getStandaloneJre() {
        if (os.isWindows()) {
            File jreDir;
            if (javaVersion.isJava5()) {
                jreDir = new File(javaHome.getParentFile(), String.format("jre%s", SystemProperties.getJavaVersion()));
            } else {
                jreDir = new File(javaHome.getParentFile(), String.format("jre%s", javaVersion.getMajorVersion()));
            }
            if (jreDir.isDirectory()) {
                return new DefaultJre(jreDir);
            }
        }
        if (!new File(javaHome, "jre").isDirectory()) {
            return new DefaultJre(javaHome);
        }
        return null;
    }

    /**
     * Locates the JRE installation for this JVM.
     */
    public Jre getJre() {
        File jreDir = new File(javaBase, "jre");
        if (jreDir.isDirectory()) {
            return new DefaultJre(jreDir);
        }
        return new DefaultJre(javaBase);
    }

    private File findToolsJar(File javaHome) {
        File toolsJar = new File(javaHome, "lib/tools.jar");
        if (toolsJar.exists()) {
            return toolsJar;
        }
        if (javaHome.getName().equalsIgnoreCase("jre")) {
            javaHome = javaHome.getParentFile();
            toolsJar = new File(javaHome, "lib/tools.jar");
            if (toolsJar.exists()) {
                return toolsJar;
            }
        }

        if (os.isWindows()) {
            String version = SystemProperties.getJavaVersion();
            if (javaHome.getName().matches("jre\\d+") || javaHome.getName().equals(String.format("jre%s", version))) {
                javaHome = new File(javaHome.getParentFile(), String.format("jdk%s", version));
                toolsJar = new File(javaHome, "lib/tools.jar");
                if (toolsJar.exists()) {
                    return toolsJar;
                }
            }
        }

        return null;
    }

    /**
     * {@inheritDoc}
     */
    public Map<String, ?> getInheritableEnvironmentVariables(Map<String, ?> envVars) {
        return envVars;
    }

    public boolean isIbmJvm() {
        return false;
    }

    static class IbmJvm extends Jvm {
        IbmJvm(OperatingSystem os, File suppliedJavaBase) {
            super(os, suppliedJavaBase);
        }

        @Override
        public boolean isIbmJvm() {
            return true;
        }
    }

    /**
     * Note: Implementation assumes that an Apple JVM always comes with a JDK rather than a JRE,
     * but this is likely an over-simplification.
     */
    static class AppleJvm extends Jvm {
        AppleJvm(OperatingSystem os) {
            super(os);
        }

        AppleJvm(OperatingSystem current, File javaHome) {
            super(current, javaHome);
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public File getRuntimeJar() {
            File javaHome = super.getJavaHome();
            File runtimeJar = new File(javaHome.getParentFile(), "Classes/classes.jar");
            return runtimeJar.exists() ? runtimeJar : null;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public File getToolsJar() {
            return getRuntimeJar();
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public Map<String, ?> getInheritableEnvironmentVariables(Map<String, ?> envVars) {
            Map<String, Object> vars = new HashMap<String, Object>();
            for (Map.Entry<String, ?> entry : envVars.entrySet()) {
                if (entry.getKey().matches("APP_NAME_\\d+") || entry.getKey().matches("JAVA_MAIN_CLASS_\\d+")) {
                    continue;
                }
                vars.put(entry.getKey(), entry.getValue());
            }
            return vars;
        }
    }

    private static class DefaultJre extends Jre {
        private final File jreDir;

        public DefaultJre(File jreDir) {
            this.jreDir = jreDir;
        }

        @Override
        public File getHomeDir() {
            return jreDir;
        }
    }
}
TOP

Related Classes of org.gradle.internal.jvm.Jvm$AppleJvm

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.