Example #1
0
    def _find_java():
        """
        Find location of the java executable (helper for `._launch_server()`).

        This method is not particularly robust, and may require additional tweaking for different platforms...
        :return: Path to the java executable.
        :raises H2OStartupError: if java cannot be found.
        """
        java = "java.exe" if sys.platform == "win32" else "java"

        h2o_java = os.getenv("H2O_JAVA_HOME")
        if h2o_java:
            full_path = os.path.join(h2o_java, "bin", java)
            if not os.path.exists(full_path):
                raise H2OStartupError(
                    "Environment variable H2O_JAVA_HOME is set to '%d' "
                    "but this location doesn't appear to be a valid Java Home directory, "
                    "unset environment variable or provide valid path to Java Home."
                    % h2o_java)
            return full_path

        # is java callable directly (doesn't work on windows it seems)?
        if os.access(java, os.X_OK):
            return java

        # Can Java be found on the PATH?
        for path in os.getenv("PATH").split(
                os.pathsep):  # not same as os.path.sep!
            full_path = os.path.join(path, java)
            if os.access(full_path, os.X_OK):
                return full_path

        # check if JAVA_HOME is set (for Windows)
        if os.getenv("JAVA_HOME"):
            full_path = os.path.join(os.getenv("JAVA_HOME"), "bin", java)
            if os.path.exists(full_path):
                return full_path

        # check "/Program Files" and "/Program Files (x86)" on Windows
        if sys.platform == "win32":
            # On Windows, backslash on the drive letter is necessary, otherwise os.path.join produces an invalid path
            program_folders = [
                os.path.join("C:\\", "Program Files", "Java"),
                os.path.join("C:\\", "Program Files (x86)", "Java"),
                os.path.join("C:\\", "ProgramData", "Oracle", "Java")
            ]
            for folder in program_folders:
                for dirpath, dirnames, filenames in os.walk(folder):
                    if java in filenames:
                        return os.path.join(dirpath, java)

        # not found...
        raise H2OStartupError(
            "Cannot find Java. Please install the latest JRE from\n"
            "http://docs.h2o.ai/h2o/latest-stable/h2o-docs/welcome.html#java-requirements"
        )
Example #2
0
    def _jar_paths():
        """Produce potential paths for an h2o.jar executable."""
        
        # PUBDEV-3534 hook to use arbitrary h2o.jar
        own_jar = os.getenv("H2O_JAR_PATH", "")
        if own_jar != "":
            if not os.path.isfile(own_jar):
                raise H2OStartupError("Environment variable H2O_JAR_PATH is set to '%d' but file does not exists, unset environment variable or provide valid path to h2o.jar file." % own_jar)
            yield own_jar
        
        # Check if running from an h2o-3 src folder (or any subfolder), in which case use the freshly-built h2o.jar
        cwd_chunks = os.path.abspath(".").split(os.path.sep)
        for i in range(len(cwd_chunks), 0, -1):
            if cwd_chunks[i - 1] == "h2o-3":
                yield os.path.sep.join(cwd_chunks[:i] + ["build", "h2o.jar"])
        # Then check the backend/bin folder:
        # (the following works assuming this code is located in h2o/backend/server.py file)
        backend_dir = os.path.split(os.path.realpath(__file__))[0]
        yield os.path.join(backend_dir, "bin", "h2o.jar")

        # Then try several old locations where h2o.jar might have been installed
        prefix1 = prefix2 = sys.prefix
        # On Unix-like systems Python typically gets installed into /Library/... or /System/Library/... If one of
        # those paths is sys.prefix, then we also build its counterpart.
        if prefix1.startswith(os.path.sep + "Library"):
            prefix2 = os.path.join("", "System", prefix1)
        elif prefix1.startswith(os.path.sep + "System"):
            prefix2 = prefix1[len(os.path.join("", "System")):]
        yield os.path.join(prefix1, "h2o_jar", "h2o.jar")
        yield os.path.join(os.path.abspath(os.sep), "usr", "local", "h2o_jar", "h2o.jar")
        yield os.path.join(prefix1, "local", "h2o_jar", "h2o.jar")
        yield os.path.join(get_config_var("userbase"), "h2o_jar", "h2o.jar")
        yield os.path.join(prefix2, "h2o_jar", "h2o.jar")
Example #3
0
 def _check_java(java, verbose):
     jver_bytes = subprocess.check_output([java, "-version"], stderr=subprocess.STDOUT)
     jver = jver_bytes.decode(encoding="utf-8", errors="ignore")
     if verbose:
         print("  Java Version: " + jver.strip().replace("\n", "; "))
     if "GNU libgcj" in jver:
         raise H2OStartupError("Sorry, GNU Java is not supported for H2O.\n"
                               "Please download the latest 64-bit Java SE JDK from Oracle.")
     if "Client VM" in jver:
         warn("  You have a 32-bit version of Java. H2O works best with 64-bit Java.\n"
              "  Please download the latest 64-bit Java SE JDK from Oracle.\n")
Example #4
0
    def _find_java():
        """
        Find location of the java executable (helper for `._launch_server()`).

        This method is not particularly robust, and may require additional tweaking for different platforms...
        :return: Path to the java executable.
        :raises H2OStartupError: if java cannot be found.
        """
        # is java in PATH?
        if os.access("java", os.X_OK):
            return "java"
        for path in os.getenv("PATH").split(
                os.pathsep):  # not same as os.path.sep!
            full_path = os.path.join(path, "java")
            if os.access(full_path, os.X_OK):
                return full_path

        # check if JAVA_HOME is set (for Windows)
        if os.getenv("JAVA_HOME"):
            return os.path.join(os.getenv("JAVA_HOME"), "bin", "java.exe")

        # check "/Program Files" and "/Program Files (x86)" on Windows
        if sys.platform == "win32":
            # On Windows, backslash on the drive letter is necessary, otherwise os.path.join produces an invalid path
            program_folders = [
                os.path.join("C:\\", "Program Files", "Java"),
                os.path.join("C:\\", "Program Files (x86)", "Java")
            ]
            # Look for JDK
            for folder in program_folders:
                if not os.path.exists(folder): continue
                for jdk in os.listdir(folder):
                    if "jdk" not in jdk.lower(): continue
                    path = os.path.join(folder, jdk, "bin", "java.exe")
                    if os.path.exists(path):
                        return path
            # check for JRE and warn
            for folder in program_folders:
                path = os.path.join(folder, "jre7", "bin", "java.exe")
                if os.path.exists(path):
                    warn("Found JRE at " + path +
                         "; but H2O requires the JDK to run.")
        # not found...
        raise H2OStartupError(
            "Cannot find Java. Please install the latest JDK from\n"
            "http://www.oracle.com/technetwork/java/javase/downloads/index.html"
        )
Example #5
0
    def _find_jar(self, path0=None):
        """
        Return the location of an h2o.jar executable.

        :param path0: Explicitly given h2o.jar path. If provided, then we will simply check whether the file is there,
            otherwise we will search for an executable in locations returned by ._jar_paths().

        :raises H2OStartupError: if no h2o.jar executable can be found.
        """
        jar_paths = [path0] if path0 else self._jar_paths()
        searched_paths = []
        for jp in jar_paths:
            searched_paths.append(jp)
            if os.path.exists(jp):
                return jp
        raise H2OStartupError("Cannot start local server: h2o.jar not found. Paths searched:\n" +
                              "".join("    %s\n" % s for s in searched_paths))
Example #6
0
    def _find_java():
        """
        Find location of the java executable (helper for `._launch_server()`).

        This method is not particularly robust, and may require additional tweaking for different platforms...
        :return: Path to the java executable.
        :raises H2OStartupError: if java cannot be found.
        """
        # is java callable directly (doesn't work on windows it seems)?
        java = "java.exe" if sys.platform == "win32" else "java"
        if os.access(java, os.X_OK):
            return java

        # Can Java be found on the PATH?
        for path in os.getenv("PATH").split(
                os.pathsep):  # not same as os.path.sep!
            full_path = os.path.join(path, java)
            if os.access(full_path, os.X_OK):
                return full_path

        # check if JAVA_HOME is set (for Windows)
        if os.getenv("JAVA_HOME"):
            full_path = os.path.join(os.getenv("JAVA_HOME"), "bin", java)
            if os.path.exists(full_path):
                return full_path

        # check "/Program Files" and "/Program Files (x86)" on Windows
        if sys.platform == "win32":
            # On Windows, backslash on the drive letter is necessary, otherwise os.path.join produces an invalid path
            program_folders = [
                os.path.join("C:\\", "Program Files", "Java"),
                os.path.join("C:\\", "Program Files (x86)", "Java"),
                os.path.join("C:\\", "ProgramData", "Oracle", "Java")
            ]
            for folder in program_folders:
                for dirpath, dirnames, filenames in os.walk(folder):
                    if java in filenames:
                        return os.path.join(dirpath, java)

        # not found...
        raise H2OStartupError(
            "Cannot find Java. Please install the latest JRE from\n"
            "http://www.oracle.com/technetwork/java/javase/downloads/index.html"
        )
Example #7
0
 def _has_compatible_version(java_version):
     pattern = re.compile("1\\.[1-7]\\.")
     if pattern.search(java_version):
         raise H2OStartupError("Your java is not supported: " +
                               java_version.strip().replace("\n", "; "))
Example #8
0
    def _launch_server(self, port, baseport, mmax, mmin, ea, nthreads):
        """Actually start the h2o.jar executable (helper method for `.start()`)."""
        self._ip = "127.0.0.1"

        # Find Java and check version. (Note that subprocess.check_output returns the output as a bytes object)
        java = self._find_java()
        jver_bytes = subprocess.check_output([java, "-version"], stderr=subprocess.STDOUT)
        jver = jver_bytes.decode(encoding="utf-8", errors="ignore")
        if self._verbose:
            print("  Java Version: " + jver.strip().replace("\n", "; "))
        if "GNU libgcj" in jver:
            raise H2OStartupError("Sorry, GNU Java is not supported for H2O.\n"
                                  "Please download the latest 64-bit Java SE JDK from Oracle.")
        if "Client VM" in jver:
            warn("  You have a 32-bit version of Java. H2O works best with 64-bit Java.\n"
                 "  Please download the latest 64-bit Java SE JDK from Oracle.\n")

        if self._verbose:
            print("  Starting server from " + self._jar_path)
            print("  Ice root: " + self._ice_root)

        # Construct java command to launch the process
        cmd = [java]

        # ...add JVM options
        cmd += ["-ea"] if ea else []
        for (mq, num) in [("-Xms", mmin), ("-Xmx", mmax)]:
            if num is None: continue
            numstr = "%dG" % (num >> 30) if num == (num >> 30) << 30 else \
                     "%dM" % (num >> 20) if num == (num >> 20) << 20 else \
                     str(num)
            cmd += [mq + numstr]
        cmd += ["-verbose:gc", "-XX:+PrintGCDetails", "-XX:+PrintGCTimeStamps"]
        cmd += ["-jar", self._jar_path]  # This should be the last JVM option

        # ...add H2O options
        cmd += ["-ip", self._ip]
        cmd += ["-port", str(port)] if port else []
        cmd += ["-baseport", str(baseport)] if baseport else []
        cmd += ["-ice_root", self._ice_root]
        cmd += ["-nthreads", str(nthreads)] if nthreads > 0 else []
        cmd += ["-name", "H2O_from_python_%s" % self._tmp_file("salt")]
        # Warning: do not change to any higher log-level, otherwise we won't be able to know which port the
        # server is listening to.
        cmd += ["-log_level", "INFO"]

        # Create stdout and stderr files
        self._stdout = self._tmp_file("stdout")
        self._stderr = self._tmp_file("stderr")
        cwd = os.path.abspath(os.getcwd())
        out = open(self._stdout, "w")
        err = open(self._stderr, "w")
        if self._verbose:
            print("  JVM stdout: " + out.name)
            print("  JVM stderr: " + err.name)

        # Launch the process
        win32 = sys.platform == "win32"
        flags = getattr(subprocess, "CREATE_NEW_PROCESS_GROUP", 0) if win32 else 0
        prex = os.setsid if not win32 else None
        try:
            proc = subprocess.Popen(args=cmd, stdout=out, stderr=err, cwd=cwd, creationflags=flags, preexec_fn=prex)
        except OSError as e:
            traceback = getattr(e, "child_traceback", None)
            raise H2OServerError("Unable to start server: %s" % e, traceback)

        # Wait until the server is up-and-running
        giveup_time = time.time() + self._TIME_TO_START
        while True:
            if proc.poll() is not None:
                raise H2OServerError("Server process terminated with error code %d" % proc.returncode)
            ret = self._get_server_info_from_logs()
            if ret:
                self._scheme = ret[0]
                self._ip = ret[1]
                self._port = ret[2]
                self._process = proc
                break
            if time.time() > giveup_time:
                elapsed_time = time.time() - (giveup_time - self._TIME_TO_START)
                raise H2OServerError("Server wasn't able to start in %f seconds." % elapsed_time)
            time.sleep(0.2)