8000 Add JRE dependency to Java components (#11462) · localstack/localstack@de27208 · GitHub
[go: up one dir, main page]

Skip to content

Commit de27208

Browse files
Add JRE dependency to Java components (#11462)
1 parent 4e719dc commit de27208

File tree

10 files changed

+100
-26
lines changed

10 files changed

+100
-26
lines changed

Dockerfile

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# base: Stage which installs necessary runtime dependencies (OS packages, java,...)
2+
# base: Stage which installs necessary runtime dependencies (OS packages, etc.)
33
#
44
FROM python:3.11.10-slim-bookworm@sha256:5501a4fe605abe24de87c2f3d6cf9fd760354416a0cad0296cf284fddcdca9e2 AS base
55
ARG TARGETARCH
@@ -91,7 +91,6 @@ ADD bin/hosts /etc/hosts
9191
# expose default environment
9292
# Set edge bind host so localstack can be reached by other containers
9393
# set library path and default LocalStack hostname
94-
ENV LD_LIBRARY_PATH=$JAVA_HOME/lib:$JAVA_HOME/lib/server
9594
ENV USER=localstack
9695
ENV PYTHONUNBUFFERED=1
9796

@@ -157,18 +156,12 @@ RUN SETUPTOOLS_SCM_PRETEND_VERSION_FOR_LOCALSTACK_CORE=${LOCALSTACK_BUILD_VERSIO
157156
RUN --mount=type=cache,target=/root/.cache \
158157
--mount=type=cache,target=/var/lib/localstack/cache \
159158
source .venv/bin/activate && \
160-
python -m localstack.cli.lpm install java --version 11 && \
161159
python -m localstack.cli.lpm install \
162160
lambda-runtime \
163161
dynamodb-local && \
164162
chown -R localstack:localstack /usr/lib/localstack && \
165163
chmod -R 777 /usr/lib/localstack
166164

167-
# Set up Java
168-
ENV JAVA_HOME /usr/lib/localstack/java/11
169-
RUN ln -s $JAVA_HOME/bin/java /usr/bin/java
170-
ENV PATH="${PATH}:${JAVA_HOME}/bin"
171-
172165
# link the python package installer virtual environments into the localstack venv
173166
RUN echo /var/lib/localstack/lib/python-packages/lib/python3.11/site-packages > localstack-var-python-packages-venv.pth && \
174167
mv localstack-var-python-packages-venv.pth .venv/lib/python*/site-packages/

localstack-core/localstack/packages/java.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,41 @@
2525
}
2626

2727

28+
class JavaInstallerMixin:
29+
"""
30+
Mixin class for packages that depend on Java. It introduces methods that install Java and help build environment.
31+
"""
32+
33+
def _prepare_installation(self, target: InstallTarget) -> None:
34+
java_package.install(target=target)
35+
36+
def get_java_home(self) -> str | None:
37+
"""
38+
Returns path to JRE installation.
39+
"""
40+
return java_package.get_installer().get_java_home()
41+
42+
def get_java_env_vars(self, path: str = None) -> dict[str, str]:
43+
"""
44+
Returns environment variables pointing to the Java installation. This is useful to build the environment where
45+
the application will run.
46+
47+
:param path: If not specified, the value of PATH will be obtained from the environment
48+
:return: dict consisting of two items:
49+
- JAVA_HOME: path to JRE installation
50+
- PATH: the env path variable updated with JRE bin path
51+
"""
52+
java_home = self.get_java_home()
53+
java_bin = f"{java_home}/bin"
54+
55+
path = path or os.environ["PATH"]
56+
57+
return {
58+
"JAVA_HOME": java_home,
59+
"PATH": f"{java_bin}:{path}",
60+
}
61+
62+
2863
class JavaPackageInstaller(ArchiveDownloadAndExtractInstaller):
2964
def __init__(self, version: str):
3065
super().__init__("java", version, extract_single_directory=True)
@@ -81,7 +116,7 @@ def _post_process(self, target: InstallTarget) -> None:
81116
rm_rf(target_directory)
82117
os.rename(minimal_jre_path, target_directory)
83118

84-
def get_java_home(self) -> str:
119+
def get_java_home(self) -> str | None:
85120
"""
86121
Get JAVA_HOME for this installation of Java.
87122
"""

localstack-core/localstack/services/dynamodb/packages.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from localstack import config
55
from localstack.constants import ARTIFACTS_REPO, MAVEN_REPO_URL
66
from localstack.packages import InstallTarget, Package, PackageInstaller
7+
from localstack.packages.java import JavaInstallerMixin
78
from localstack.utils.archives import (
89
download_and_extract_with_retry,
910
update_jar_manifest,
@@ -37,7 +38,7 @@ def get_versions(self) -> List[str]:
3738
return ["latest"]
3839

3940

40-
class DynamoDBLocalPackageInstaller(PackageInstaller):
41+
class DynamoDBLocalPackageInstaller(JavaInstallerMixin, PackageInstaller):
4142
def __init__(self):
4243
super().__init__("dynamodb-local", "latest")
4344

localstack-core/localstack/services/dynamodb/server.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,17 +150,23 @@ def _create_shell_command(self) -> list[str]:
150150
return cmd + parameters
151151

152152
def do_start_thread(self) -> FuncThread:
153-
dynamodblocal_package.install()
153+
dynamodblocal_installer = dynamodblocal_package.get_installer()
154+
dynamodblocal_installer.install()
154155

155156
cmd = self._create_shell_command()
157+
env_vars = {
158+
"DDB_LOCAL_TELEMETRY": "0",
159+
**dynamodblocal_installer.get_java_env_vars(),
160+
}
161+
156162
LOG.debug("Starting DynamoDB Local: %s", cmd)
157163
t = ShellCommandThread(
158164
cmd,
159165
strip_color=True,
160166
log_listener=_log_listener,
161167
auto_restart=True,
162168
name="dynamodb-local",
163-
env_vars={"DDB_LOCAL_TELEMETRY": "0"},
169+
env_vars=env_vars,
164170
)
165171
TMP_THREADS.append(t)
166172
t.start()

localstack-core/localstack/services/events/event_ruler.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import os
33
from functools import cache
44
from pathlib import Path
5+
from typing import Tuple
56

67
from localstack.services.events.models import InvalidEventPatternException
78
from localstack.services.events.packages import event_ruler_package
@@ -25,16 +26,27 @@ def start_jvm() -> None:
2526
jpype_config.destroy_jvm = False
2627

2728
if not jpype.isJVMStarted():
28-
event_ruler_libs_path = get_event_ruler_libs_path()
29+
jvm_lib, event_ruler_libs_path = get_jpype_lib_paths()
2930
event_ruler_libs_pattern = event_ruler_libs_path.joinpath("*")
30-
jpype.startJVM(classpath=[event_ruler_libs_pattern])
31+
32+
jpype.startJVM(str(jvm_lib), classpath=[event_ruler_libs_pattern])
3133

3234

3335
@cache
34-
def get_event_ruler_libs_path() -> Path:
36+
def get_jpype_lib_paths() -> Tuple[Path, Path]:
37+
"""
38+
Downloads Event Ruler, its dependencies and returns a tuple of:
39+
- Path to libjvm.so to be used by JPype as jvmpath. JPype requires this to start the JVM.
40+
See https://jpype.readthedocs.io/en/latest/userguide.html#path-to-the-jvm
41+
- Path to Event Ruler libraries to be used by JPype as classpath
42+
"""
3543
installer = event_ruler_package.get_installer()
3644
installer.install()
37-
return Path(installer.get_installed_dir())
45+
46+
java_home = installer.get_java_home()
47+
jvm_lib = Path(java_home) / "lib" / "server" / "libjvm.so"
48+
49+
return jvm_lib, Path(installer.get_installed_dir())
3850

3951

4052
def matches_rule(event: str, rule: str) -> bool:

localstack-core/localstack/services/events/packages.py

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,37 @@
11
from localstack.packages import Package, PackageInstaller
22
from localstack.packages.core import MavenPackageInstaller
3+
from localstack.packages.java import JavaInstallerMixin
34

5+
# Map of Event Ruler version to Jackson version
46
# https://central.sonatype.com/artifact/software.amazon.event.ruler/event-ruler
5-
EVENT_RULER_VERSION = "1.7.3"
67
# The dependent jackson.version is defined in the Maven POM File of event-ruler
7-
JACKSON_VERSION = "2.16.2"
8+
EVENT_RULER_VERSIONS = {
9+
"1.7.3": "2.16.2",
10+
}
11+
12+
EVENT_RULER_DEFAULT_VERSION = "1.7.3"
813

914

1015
class EventRulerPackage(Package):
1116
def __init__(self):
12-
super().__init__("EventRulerLibs", EVENT_RULER_VERSION)
17+
super().__init__("EventRulerLibs", EVENT_RULER_DEFAULT_VERSION)
1318

1419
def get_versions(self) -> list[str]:
15-
return [EVENT_RULER_VERSION]
20+
return list(EVENT_RULER_VERSIONS.keys())
1621

1722
def _get_installer(self, version: str) -> PackageInstaller:
18-
return MavenPackageInstaller(
19-
f"pkg:maven/software.amazon.event.ruler/event-ruler@{EVENT_RULER_VERSION}",
20-
f"pkg:maven/com.fasterxml.jackson.core/jackson-annotations@{JACKSON_VERSION}",
21-
f"pkg:maven/com.fasterxml.jackson.core/jackson-core@{JACKSON_VERSION}",
22-
f"pkg:maven/com.fasterxml.jackson.core/jackson-databind@{JACKSON_VERSION}",
23+
return EventRulerPackageInstaller(version)
24+
25+
26+
class EventRulerPackageInstaller(JavaInstallerMixin, MavenPackageInstaller):
27+
def __init__(self, version: str):
28+
jackson_version = EVENT_RULER_VERSIONS[version]
29+
30+
super().__init__(
31+
f"pkg:maven/software.amazon.event.ruler/event-ruler@{version}",
32+
f"pkg:maven/com.fasterxml.jackson.core/jackson-annotations@{jackson_version}",
33+
f"pkg:maven/com.fasterxml.jackson.core/jackson-core@{jackson_version}",
34+
f"pkg:maven/com.fasterxml.jackson.core/jackson-databind@{jackson_version}",
2335
)
2436

2537

localstack-core/localstack/services/opensearch/cluster.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,7 @@ def _create_run_command(
466466

467467
def _create_env_vars(self, directories: Directories) -> Dict:
468468
env_vars = {
469+
"JAVA_HOME": os.path.join(directories.install, "jdk"),
469470
"OPENSEARCH_JAVA_OPTS": os.environ.get("OPENSEARCH_JAVA_OPTS", "-Xms200m -Xmx600m"),
470471
"OPENSEARCH_TMPDIR": directories.tmp,
471472
}
@@ -689,6 +690,7 @@ def _base_settings(self, dirs) -> CommandSettings:
689690

690691
def _create_env_vars(self, directories: Directories) -> Dict:
691692
return {
693+
"JAVA_HOME": os.path.join(directories.install, "jdk"),
692694
"ES_JAVA_OPTS": os.environ.get("ES_JAVA_OPTS", "-Xms200m -Xmx600m"),
693695
"ES_TMPDIR": directories.tmp,
694696
}

localstack-core/localstack/services/stepfunctions/legacy/stepfunctions_starter.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ def do_start_thread(self) -> FuncThread:
4242
return t
4343

4444
def generate_env_vars(self) -> Dict[str, Any]:
45+
sfn_local_installer = stepfunctions_local_package.get_installer()
46+
4547
return {
48+
**sfn_local_installer.get_java_env_vars(),
4649
"EDGE_PORT": config.GATEWAY_LISTEN[0].port,
4750
"EDGE_PORT_HTTP": config.GATEWAY_LISTEN[0].port,
4851
"DATA_DIR": config.dirs.data,

localstack-core/localstack/services/stepfunctions/packages.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from localstack.constants import ARTIFACTS_REPO, MAVEN_REPO_URL
1010
from localstack.packages import InstallTarget, Package, PackageInstaller
1111
from localstack.packages.core import ExecutableInstaller
12+
from localstack.packages.java import JavaInstallerMixin
1213
from localstack.utils.archives import add_file_to_jar, untar, update_jar_manifest
1314
from localstack.utils.files import file_exists_not_empty, mkdir, new_tmp_file, rm_rf
1415
from localstack.utils.http import download
@@ -73,7 +74,7 @@ def _get_installer(self, version: str) -> PackageInstaller:
7374
return StepFunctionsLocalPackageInstaller("stepfunctions-local", version)
7475

7576

76-
class StepFunctionsLocalPackageInstaller(ExecutableInstaller):
77+
class StepFunctionsLocalPackageInstaller(JavaInstallerMixin, ExecutableInstaller):
7778
def _get_install_marker_path(self, install_dir: str) -> str:
7879
return os.path.join(install_dir, "StepFunctionsLocal.jar")
7980

localstack-core/localstack/utils/kinesis/kinesis_connector.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
from localstack import config
1515
from localstack.constants import LOCALSTACK_ROOT_FOLDER, LOCALSTACK_VENV_FOLDER
16+
from localstack.packages.java import java_package
1617
from localstack.utils.aws import arns
1718
from localstack.utils.files import TMP_FILES, chmod_r, save_file
1819
from localstack.utils.kinesis import kclipy_helper
@@ -240,12 +241,20 @@ def _start_kcl_client_process(
240241
):
241242
# make sure to convert stream ARN to stream name
242243
stream_name = arns.kinesis_stream_name(stream_name)
244+
245+
# install Java
246+
java_installer = java_package.get_installer()
247+
java_installer.install()
248+
java_home = java_installer.get_java_home()
249+
243250
# disable CBOR protocol, enforce use of plain JSON
244251
# TODO evaluate why?
245252
env_vars = {
246253
"AWS_CBOR_DISABLE": "true",
247254
"AWS_ACCESS_KEY_ID": account_id,
248255
"AWS_SECRET_ACCESS_KEY": account_id,
256+
"JAVA_HOME": java_home,
257+
"PATH": f"{java_home}/bin:{os.getenv('PATH')}",
249258
}
250259

251260
events_file = os.path.join(tempfile.gettempdir(), f"kclipy.{short_uid()}.fifo")

0 commit comments

Comments
 (0)
0