Bug 1477487 - Part 1: Look for java and pin to Java 1.8 in |mach bootstrap|; r=agi

What is happening is that distribution JRE and JDK packages roll
forward, installing a different version of Java than what is expected.
We don't check the version installed, so sadness ensues.

Right now, we require Java 1.8 to build, but in the near future, after
Android-Gradle plugin 3.2.1+, we'll be free to use later Java
versions.

However, Android's `sdkmanager` itself requires exactly Java 1.8.  We
only require `sdkmanager` to install `emulator`, really -- everything
else will be fetched by Gradle -- but I don't want to unravel that
right now.

So let's just provide decent error messages and try to prevent the
worst of the footguns.

Differential Revision: https://phabricator.services.mozilla.com/D16137

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Nick Alexander 2019-01-17 21:30:29 +00:00
Родитель 2a42763c8f
Коммит 57c01fa819
7 изменённых файлов: 67 добавлений и 20 удалений

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

@ -296,7 +296,7 @@ def suggest_mozconfig(os_name, artifact_mode=False, java_bin_path=None):
extra_lines = [] extra_lines = []
if java_bin_path: if java_bin_path:
extra_lines += [ extra_lines += [
'# With the following java and javac:', '# With the following java:',
'ac_add_options --with-java-bin-path="{}"'.format(java_bin_path), 'ac_add_options --with-java-bin-path="{}"'.format(java_bin_path),
] ]
if extra_lines: if extra_lines:

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

@ -120,6 +120,7 @@ class ArchlinuxBootstrapper(NodeInstall, StyloInstall,
raise e raise e
# 2. Android pieces. # 2. Android pieces.
self.ensure_java()
from mozboot import android from mozboot import android
android.ensure_android('linux', artifact_mode=artifact_mode, android.ensure_android('linux', artifact_mode=artifact_mode,
no_interactive=self.no_interactive) no_interactive=self.no_interactive)

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

@ -747,3 +747,57 @@ class BaseBootstrapper(object):
if h.hexdigest() != hexhash: if h.hexdigest() != hexhash:
os.remove(dest) os.remove(dest)
raise ValueError('Hash of downloaded file does not match expected hash') raise ValueError('Hash of downloaded file does not match expected hash')
def ensure_java(self, extra_search_dirs=()):
"""Verify the presence of java.
Note that we currently require a JDK (not just a JRE) because we
use `jarsigner` in local builds.
Soon we won't require Java 1.8 to build (after Bug 1515248 and
we use Android-Gradle plugin 3.2.1), but the Android
`sdkmanager` tool still requires exactly 1.8. Sigh. Note that
we no longer require javac explicitly; it's fetched by
Gradle.
"""
if 'JAVA_HOME' in os.environ:
extra_search_dirs += (os.path.join(os.environ['JAVA_HOME'], 'bin'),)
java = self.which('java', extra_search_dirs)
if not java:
raise Exception('You need to have Java version 1.8 installed. '
'Please visit http://www.java.com/en/download '
'to get version 1.8.')
try:
output = subprocess.check_output([java,
'-XshowSettings:properties',
'-version'],
stderr=subprocess.STDOUT).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 not len(version) == 1:
raise Exception('You need to have Java version 1.8 installed '
'(found {} but could not parse version "{}"). '
'Check the JAVA_HOME environment variable. '
'Please visit http://www.java.com/en/download '
'to get version 1.8.'.format(java, output))
version = version[0].split(' = ')[-1]
if version not in ['1.8', '8']:
raise Exception('You need to have Java version 1.8 installed '
'(found {} with version "{}"). '
'Check the JAVA_HOME environment variable. '
'Please visit http://www.java.com/en/download '
'to get version 1.8.'.format(java, version))
except subprocess.CalledProcessError as e:
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))

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

@ -121,6 +121,7 @@ class CentOSFedoraBootstrapper(NodeInstall, StyloInstall,
# Install Android specific packages. # Install Android specific packages.
self.dnf_install(*self.mobile_android_packages) self.dnf_install(*self.mobile_android_packages)
self.ensure_java()
from mozboot import android from mozboot import android
android.ensure_android('linux', artifact_mode=artifact_mode, android.ensure_android('linux', artifact_mode=artifact_mode,
no_interactive=self.no_interactive) no_interactive=self.no_interactive)

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

@ -78,10 +78,8 @@ class DebianBootstrapper(NodeInstall, StyloInstall, ClangStaticAnalysisInstall,
# These are common packages for building Firefox for Android # These are common packages for building Firefox for Android
# (mobile/android) for all Debian-derived distros (such as Ubuntu). # (mobile/android) for all Debian-derived distros (such as Ubuntu).
MOBILE_ANDROID_COMMON_PACKAGES = [ MOBILE_ANDROID_COMMON_PACKAGES = [
'default-jdk', 'openjdk-8-jdk-headless', # Android's `sdkmanager` requires Java 1.8 exactly.
'wget', # For downloading the Android SDK and NDK. 'wget', # For downloading the Android SDK and NDK.
'libncurses5:i386', # See comments about i386 below.
'libstdc++6:i386',
] ]
# Subclasses can add packages to this variable to have them installed. # Subclasses can add packages to this variable to have them installed.
@ -139,18 +137,10 @@ class DebianBootstrapper(NodeInstall, StyloInstall, ClangStaticAnalysisInstall,
# Multi-part process: # Multi-part process:
# 1. System packages. # 1. System packages.
# 2. Android SDK. Android NDK only if we are not in artifact mode. Android packages. # 2. Android SDK. Android NDK only if we are not in artifact mode. Android packages.
# 1. This is hard to believe, but the Android SDK binaries are 32-bit
# and that conflicts with 64-bit Debian and Ubuntu installations out of
# the box. The solution is to add the i386 architecture. See
# "Troubleshooting Ubuntu" at
# http://developer.android.com/sdk/installing/index.html?pkg=tools.
self.run_as_root(['dpkg', '--add-architecture', 'i386'])
# After adding a new arch, the list of packages has to be updated
self.apt_update()
self.apt_install(*self.mobile_android_packages) self.apt_install(*self.mobile_android_packages)
# 2. Android pieces. # 2. Android pieces.
self.ensure_java()
from mozboot import android from mozboot import android
android.ensure_android('linux', artifact_mode=artifact_mode, android.ensure_android('linux', artifact_mode=artifact_mode,
no_interactive=self.no_interactive) no_interactive=self.no_interactive)

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

@ -109,6 +109,7 @@ class GentooBootstrapper(NodeInstall, StyloInstall, ClangStaticAnalysisInstall,
'--autounmask-continue', '--ask', '--autounmask-continue', '--ask',
'dev-java/oracle-jdk-bin']) 'dev-java/oracle-jdk-bin'])
self.ensure_java()
from mozboot import android from mozboot import android
android.ensure_android('linux', artifact_mode=artifact_mode, android.ensure_android('linux', artifact_mode=artifact_mode,
no_interactive=self.no_interactive) no_interactive=self.no_interactive)

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

@ -378,13 +378,18 @@ class OSXBootstrapper(BaseBootstrapper):
'GeckoView/Firefox for Android.') 'GeckoView/Firefox for Android.')
# 2. Android pieces. # 2. Android pieces.
# Prefer homebrew's java binary by putting it on the path first.
os.environ['PATH'] = \
'{}{}{}'.format('/Library/Java/Home/bin', os.pathsep, os.environ['PATH'])
self.ensure_java()
from mozboot import android from mozboot import android
android.ensure_android('macosx', artifact_mode=artifact_mode, android.ensure_android('macosx', artifact_mode=artifact_mode,
no_interactive=self.no_interactive) no_interactive=self.no_interactive)
def suggest_homebrew_mobile_android_mozconfig(self, artifact_mode=False): def suggest_homebrew_mobile_android_mozconfig(self, artifact_mode=False):
from mozboot import android from mozboot import android
# Path to java and javac from the caskroom/versions/java8 cask. # Path to java from the caskroom/versions/java8 cask.
android.suggest_mozconfig('macosx', artifact_mode=artifact_mode, android.suggest_mozconfig('macosx', artifact_mode=artifact_mode,
java_bin_path='/Library/Java/Home/bin') java_bin_path='/Library/Java/Home/bin')
@ -445,18 +450,13 @@ class OSXBootstrapper(BaseBootstrapper):
] ]
self._ensure_macports_packages(packages) self._ensure_macports_packages(packages)
# Verify the presence of java and javac.
if not self.which('java') or not self.which('javac'):
raise Exception('You need to have Java version 1.7 or later installed. '
'Please visit http://www.java.com/en/download/mac_download.jsp '
'to get the latest version.')
is_64bits = sys.maxsize > 2**32 is_64bits = sys.maxsize > 2**32
if not is_64bits: if not is_64bits:
raise Exception('You need a 64-bit version of Mac OS X to build ' raise Exception('You need a 64-bit version of Mac OS X to build '
'GeckoView/Firefox for Android.') 'GeckoView/Firefox for Android.')
# 2. Android pieces. # 2. Android pieces.
self.ensure_java()
from mozboot import android from mozboot import android
android.ensure_android('macosx', artifact_mode=artifact_mode, android.ensure_android('macosx', artifact_mode=artifact_mode,
no_interactive=self.no_interactive) no_interactive=self.no_interactive)