def _update_java_version()

in ccmlib/common.py [0:0]


def _update_java_version(current_java_version, current_java_home_version,
                         jvm_version=None, install_dir=None, cassandra_version=None, env=None,
                         for_build=False, info_message=None, os_env=None):

    # Internal variant accessible for tests

    if env is None:
        raise RuntimeError("env passed to _update_java_version must not be None")

    if current_java_version and current_java_home_version is None:
        raise RuntimeError("JAVA_HOME must be defined if java command is available on the PATH.")
    if current_java_version and current_java_home_version != current_java_version:
        raise RuntimeError("The version of java available on PATH {} does not match the Java version of the distribution provided via JAVA_HOME {}."
                           .format(current_java_version, current_java_home_version))

    if cassandra_version is None and install_dir:
        try:
            node_class = extension.get_cluster_class(install_dir).getNodeClass()
            cassandra_version = node_class.get_version_from_build(install_dir, cassandra=True)
        except CCMError as e:
            # when for_build cassandra_version=None is ok to pass to get_supported_jdk_versions(..)
            if not for_build:
                raise e

    # Java versions supported by the Cassandra distribution
    supported_versions = get_supported_jdk_versions(cassandra_version, install_dir, for_build, os_env if os_env else os.environ)

    # Java versions available in the current environment (JAVA_HOME, JAVAn_HOME)
    available_versions = get_available_jdk_versions(env)

    # Intersection of supported and available Java versions
    supported_available_versions = {v for v in supported_versions if v in available_versions}

    # Determine "jvm_version" - exact Java version to use if it was not explicitly provided
    if not jvm_version:
        if current_java_version and current_java_version in supported_versions:
            info('{}: Using the current Java {} available on PATH for the current invocation of Cassandra {}.'
                 .format(info_message, current_java_version, cassandra_version))
            # nothing to change in this case
            return _maybe_set_use_jdk11_env(env, current_java_version, cassandra_version)

        elif current_java_home_version and current_java_home_version in supported_versions:
            info('{}: Using the current Java {} available from JAVA_HOME for the current invocation of Cassandra {}.'
                 .format(info_message, current_java_version, cassandra_version))
            # just need to add JAVA_HOME/bin to the PATH
            return _maybe_set_use_jdk11_env(update_path_in_env(env, env['JAVA_HOME'] + '/bin'), current_java_home_version, cassandra_version)

        elif current_java_home_version and current_java_home_version not in supported_versions:
            warning('{}: The current Java {} is not supported by Cassandra {} (supported versions: {}).'
                    .format(info_message, current_java_version, cassandra_version, supported_versions))
        else:
            warning('{}: JAVA_HOME is not defined; CCM will try to find a suitable Java distribution among JAVAx_HOME env variables.')

        if len(supported_available_versions) > 0:
            info('{}: CCM has found {} Java distributions, the required Java version for Cassandra {} is {}.'.format(
                info_message, str(available_versions), cassandra_version, supported_versions))
            ref_version = current_java_home_version if current_java_home_version else max(supported_available_versions)
            # sort by the absolute difference between the current java version and the supported version
            # to use the closest version if the current version is not supported
            jvm_version = sorted(supported_available_versions, key=lambda v: abs(v - ref_version))[0]

        # No supported Java version available in the current env
        else:
            raise RuntimeError('{}: Cannot find any Java distribution for the current invocation. Available Java distributions: {}, required Java distributions: {}'
                               .format(info_message, available_versions, supported_versions))

    else:
        info('{}: Using explicitly requested Java version {} for the current invocation of Cassandra {}'
             .format(info_message, jvm_version, cassandra_version))
        if jvm_version not in available_versions:
            raise RuntimeError('{}: The explicitly requested Java version {} is not available in the current env.'
                               .format(info_message, jvm_version))
        if jvm_version not in supported_versions:
            warning('{}: The explicitly requested Java version {} is not supported by Cassandra {}.'
                    .format(info_message, jvm_version, cassandra_version))

    env['JAVA_HOME'] = env[available_versions[jvm_version]]
    return _maybe_set_use_jdk11_env(update_path_in_env(env, env['JAVA_HOME'] + '/bin'), jvm_version, cassandra_version)