Bug 1666032: ensure java from PATH == java from JDK_BIN_DIR r=rstewart

In the build process, there's two ways that java is used:
* From the path
* From the java-bin-path specified in the mozconfig

Before, to assert that both "java" usages would be consistent, the
implementation assumed that there was only a single "java" binary
per-JDK-version, and all duplicate "binaries" were symlinks to the
original.

However, in Fedora, it has two identical full binaries: one in
$JDK/bin, and one in $JDK/jre/bin. The symlink theory was incorrect.

So instead, we can assert that both "java" usages are consistent
by checking their versions and asserting that they are equivalent.

Differential Revision: https://phabricator.services.mozilla.com/D90918
This commit is contained in:
Mitchell Hentges 2020-09-21 20:59:32 +00:00
Родитель fe776d35ce
Коммит 862d284885
1 изменённых файлов: 45 добавлений и 32 удалений

Просмотреть файл

@ -858,13 +858,22 @@ class BaseBootstrapper(object):
if jarsigner and java: if jarsigner and java:
jdk_bin_dir = os.path.dirname(os.path.realpath(jarsigner)) jdk_bin_dir = os.path.dirname(os.path.realpath(jarsigner))
if (os.path.realpath(java) != jdk_bin_java = which('java', path=jdk_bin_dir)
os.path.realpath(which('java', path=jdk_bin_dir))):
# Different parts of the build process reference "java" differently.
# In bootstrap, we run some Android tooling which uses "java" from the PATH.
# Meanwhile, in build, we'll use the "java" found in the --with-java-bin-path.
# To ensure we don't run into surprises, we check that both of our "java"s are
# from the same JDK version.
path_java_version = _resolve_java_version(java)[0]
jdk_bin_version = _resolve_java_version(jdk_bin_java)[0]
if path_java_version != jdk_bin_version:
# This can happen on Ubuntu if "update-alternatives" has been # This can happen on Ubuntu if "update-alternatives" has been
# manually overridden once for either "java" or "jarsigner". # manually overridden for either "java" or "jarsigner".
raise Exception('The "java" and "jarsigner" binaries on the PATH are ' raise Exception('The "java" (JDK {}) and "jarsigner" (JDK {}) binaries on the '
'currently coming from two different JDKs. Please ' 'PATH are currently coming from two different JDKs. Please '
'resolve this, or explicitly set JAVA_HOME.') 'resolve this, or explicitly set JAVA_HOME.'
.format(path_java_version, jdk_bin_version))
if not jdk_bin_dir: if not jdk_bin_dir:
raise Exception('You need to have Java Development Kit version 1.8 installed. ' raise Exception('You need to have Java Development Kit version 1.8 installed. '
@ -872,33 +881,15 @@ class BaseBootstrapper(object):
java = which('java', path=jdk_bin_dir) java = which('java', path=jdk_bin_dir)
try: try:
output = subprocess.check_output([java, version, output = _resolve_java_version(java)
'-XshowSettings:properties',
'-version'],
stderr=subprocess.STDOUT,
universal_newlines=True).rstrip()
# -version strings are pretty free-form, like: 'java version if not version or version not in ['1.8', '8']:
# "1.8.0_192"' or 'openjdk version "11.0.1" 2018-10-16', but the raise Exception('You need to have Java Development Kit version '
# -XshowSettings:properties gives the information (to stderr, sigh) '1.8 installed (found {} but could not parse '
# like 'java.specification.version = 8'. That flag is non-standard 'version "{}"). Check the JAVA_HOME environment '
# but has been around since at least 2011. 'variable. Please install JDK 1.8 from '
version = [line for line in output.splitlines() 'https://adoptopenjdk.net/?variant=openjdk8.'
if 'java.specification.version' in line] .format(java, output))
unknown_version_exception = Exception('You need to have Java Development Kit version '
'1.8 installed (found {} but could not parse '
'version "{}"). Check the JAVA_HOME environment '
'variable. Please install JDK 1.8 from '
'https://adoptopenjdk.net/?variant=openjdk8.'
.format(java, output))
if not len(version) == 1:
raise unknown_version_exception
version = version[0].split(' = ')[-1]
if version not in ['1.8', '8']:
raise unknown_version_exception
mozconfig_builder.append(''' mozconfig_builder.append('''
# Use the same Java binary that was used in bootstrap in case the global # Use the same Java binary that was used in bootstrap in case the global
@ -909,3 +900,25 @@ class BaseBootstrapper(object):
raise Exception('Failed to get java version from {}: {}'.format(java, e.output)) raise Exception('Failed to get java version from {}: {}'.format(java, e.output))
print('Your version of Java ({}) is at least 1.8 ({}).'.format(java, version)) print('Your version of Java ({}) is at least 1.8 ({}).'.format(java, version))
def _resolve_java_version(java_path):
output = subprocess.check_output([java_path,
'-XshowSettings:properties',
'-version'],
stderr=subprocess.STDOUT,
universal_newlines=True).rstrip()
# -version strings are pretty free-form, like: 'java version
# "1.8.0_192"' or 'openjdk version "11.0.1" 2018-10-16', but the
# -XshowSettings:properties gives the information (to stderr, sigh)
# like 'java.specification.version = 8'. That flag is non-standard
# but has been around since at least 2011.
version = [line for line in output.splitlines()
if 'java.specification.version' in line]
if len(version) != 1:
return None, output
version = version[0].split(' = ')[-1]
return version, output