-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Rework Java installation #11139
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Rework Java installation #11139
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
439aedb
Use Java 21
viren-nadkarni 410822b
Merge branch 'master' into update-java-21
viren-nadkarni c3e7b6e
Add Java package
viren-nadkarni 8fbe169
Fix comments
viren-nadkarni 52d9c72
Refactor Java installer to remove OSPackageInstaller
viren-nadkarni 316b49f
Explicitly specify Java 11 as DDBLocal dependency
viren-nadkarni 378a7a2
Install JRE via LPM during Docker build
viren-nadkarni f1f8f93
Revert "Explicitly specify Java 11 as DDBLocal dependency"
viren-nadkarni 00e6433
Add comment
viren-nadkarni 2da97ff
Merge branch 'master' into update-java-21
viren-nadkarni c108cb5
Remove docker-java-home executable
viren-nadkarni a325dfc
Optimise JRE for minimise disk footprint
viren-nadkarni 88c8736
Determine the latest stable build
viren-nadkarni f1062cf
Improve already-installed detection
viren-nadkarni 1ac97fc
Improve cross-arch compatibility
viren-nadkarni c76b429
Add Thai locale
8000
viren-nadkarni 5657058
Minor rearrangement
viren-nadkarni a286af0
Add binutils package which provides objcopy command
viren-nadkarni f0d6bf7
Use distinct levels when joining paths
viren-nadkarni 4b8f57f
Fix missing f-string
viren-nadkarni 8689130
Merge branch 'master' into update-java-21
viren-nadkarni 680a58a
Define and use LocalStack user-agent string
viren-nadkarni File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
import logging | ||
import os | ||
from typing import List | ||
|
||
import requests | ||
|
||
from localstack.constants import USER_AGENT_STRING | ||
from localstack.packages import InstallTarget, Package | ||
from localstack.packages.core import ArchiveDownloadAndExtractInstaller | ||
from localstack.utils.files import rm_rf | ||
from localstack.utils.platform import Arch, get_arch, is_linux, is_mac_os | ||
from localstack.utils.run import run | ||
|
||
LOG = logging.getLogger(__name__) | ||
|
||
# Default version if not specified | ||
DEFAULT_JAVA_VERSION = "11" | ||
|
||
# Supported Java LTS versions mapped with Eclipse Temurin build semvers | ||
JAVA_VERSIONS = { | ||
"8": "8u422-b05", | ||
"11": "11.0.24+8", | ||
"17": "17.0.12+7", | ||
"21": "21.0.4+7", | ||
alexrashed marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
|
||
class JavaPackageInstaller(ArchiveDownloadAndExtractInstaller): | ||
alexrashed marked this conversation as resolved.
Show resolved
Hide resolved
|
||
def __init__(self, version: str): | ||
super().__init__("java", version, extract_single_directory=True) | ||
|
||
def _get_install_marker_path(self, install_dir: str) -> str: | ||
return os.path.join(install_dir, "bin", "java") | ||
|
||
def _get_download_url(self) -> str: | ||
try: | ||
LOG.debug("Determining the latest Java build version") | ||
return self._download_url_latest_release() | ||
except Exception as exc: # noqa | ||
LOG.debug( | ||
"Unable to determine the latest Java build version. Using pinned versions: %s", exc | ||
) | ||
return self._download_url_fallback() | ||
|
||
def _post_process(self, target: InstallTarget) -> None: | ||
target_directory = self._get_install_dir(target) | ||
minimal_jre_path = os.path.join(target.value, self.name, f"{self.version}.minimal") | ||
rm_rf(minimal_jre_path) | ||
|
||
# If jlink is not available, use the environment as is | ||
if not os.path.exists(os.path.join(target_directory, "bin", "jlink")): | ||
LOG.warning("Skipping JRE optimisation because jlink is not available") | ||
return | ||
|
||
# Build a custom JRE with only the necessary bits to minimise disk footprint | ||
LOG.debug("Optimising JRE installation") | ||
cmd = ( | ||
"bin/jlink --add-modules " | ||
# Required modules | ||
"java.base,java.desktop,java.instrument,java.management," | ||
"java.naming,java.scripting,java.sql,java.xml,jdk.compiler," | ||
# jdk.unsupported contains sun.misc.Unsafe which is required by some dependencies | ||
"jdk.unsupported," | ||
# Additional cipher suites | ||
"jdk.crypto.cryptoki," | ||
# Archive support | ||
"jdk.zipfs," | ||
# Required by MQ broker | ||
"jdk.httpserver,jdk.management,jdk.management.agent," | ||
# Required by Spark and Hadoop | ||
"java.security.jgss,jdk.security.auth," | ||
# OpenSearch requires Thai locale for segmentation support | ||
"jdk.localedata --include-locales en,th " | ||
# Supplementary args | ||
"--compress 2 --strip-debug --no-header-files --no-man-pages " | ||
# Output directory | ||
"--output " + minimal_jre_path | ||
) | ||
run(cmd, cwd=target_directory) | ||
|
||
rm_rf(target_directory) | ||
os.rename(minimal_jre_path, target_directory) | ||
|
||
def get_java_home(self) -> str: | ||
""" | ||
Get JAVA_HOME for this installation of Java. | ||
""" | ||
return self.get_installed_dir() | ||
|
||
@property | ||
def arch(self) -> str: | ||
return ( | ||
"x64" if get_arch() == Arch.amd64 else "aarch64" if get_arch() == Arch.arm64 else None | ||
) | ||
|
||
def _download_url_latest_release(self) -> str: | ||
""" | ||
Return the download URL for latest stable JDK build. | ||
""" | ||
endpoint = ( | ||
f"https://api.adoptium.net/v3/assets/latest/{self.version}/hotspot?" | ||
f"os=linux&architecture={self.arch}&image_type=jdk" | ||
) | ||
# Override user-agent because Adoptium API denies service to `requests` library | ||
response = requests.get(endpoint, headers={"user-agent": USER_AGENT_STRING}).json() | ||
return response[0]["binary"]["package"]["link"] | ||
|
||
def _download_url_fallback(self) -> str: | ||
""" | ||
Return the download URL for pinned JDK build. | ||
""" | ||
os = "linux" if is_linux() else "mac" if is_mac_os() else None | ||
|
||
semver = JAVA_VERSIONS[self.version] | ||
tag_slug = f"jdk-{semver}" | ||
semver_safe = semver.replace("+", "_") | ||
|
||
# v8 uses a different tag and version scheme | ||
if self.version == "8": | ||
semver_safe = semver_safe.replace("-", "") | ||
tag_slug = f"jdk{semver}" | ||
|
||
return ( | ||
f"https://github.com/adoptium/temurin{self.version}-binaries/releases/download/{tag_slug}/" | ||
f"OpenJDK{self.version}U-jdk_{self.arch}_{os}_hotspot_{semver_safe}.tar.gz" | ||
) | ||
|
||
|
||
class JavaPackage(Package): | ||
def __init__(self, default_version: str = DEFAULT_JAVA_VERSION): | ||
super().__init__(name="Java", default_version=default_version) | ||
|
||
def get_versions(self) -> List[str]: | ||
return list(JAVA_VERSIONS.keys()) | ||
|
||
def _get_installer(self, version): | ||
return JavaPackageInstaller(version) | ||
|
||
|
||
java_package = JavaPackage() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.