Running Java applications with jgo#
This example shows how to run an arbitrary package available from a Maven repository using jgo.
import cjdk
import jgo
import os
from contextlib import contextmanager
jgo requires Apache Maven, so we’ll install that first:
# From https://maven.apache.org/download.html
maven_url = "tgz+https://dlcdn.apache.org/maven/maven-3/3.9.6/binaries/apache-maven-3.9.6-bin.tar.gz"
maven_sha512 = "706f01b20dec0305a822ab614d51f32b07ee11d0218175e55450242e49d2156386483b506b3a4e8a03ac8611bae96395fd5eec15f50d3013d5deed6d1ee18224"
maven_dir = cjdk.cache_package("Maven", maven_url, sha512=maven_sha512)
cjdk: Installing Maven to /home/runner/.cache/cjdk
---------------------------------------------------------------------------
HTTPError Traceback (most recent call last)
Cell In[3], line 1
----> 1 maven_dir = cjdk.cache_package("Maven", maven_url, sha512=maven_sha512)
File ~/work/cjdk/cjdk/src/cjdk/_api.py:341, in cache_package(name, url, sha1, sha256, sha512, **kwargs)
336 else:
337 raise ValueError(
338 f"Cannot handle {url!r} URL (must be tgz+https or zip+https)"
339 )
--> 341 return _install.install_dir(
342 "misc-dirs", name, url, conf, checkfunc=check_hashes
343 )
File ~/work/cjdk/cjdk/src/cjdk/_install.py:50, in install_dir(prefix, name, url, conf, checkfunc)
41 _print_progress_header(conf, name)
42 _download.download_and_extract(
43 destdir,
44 url,
(...) 47 _allow_insecure_for_testing=conf._allow_insecure_for_testing,
48 )
---> 50 return _cache.permanent_directory(
51 prefix,
52 url,
53 fetch,
54 cache_dir=conf.cache_dir,
55 timeout_for_fetch_elsewhere=300,
56 )
File ~/work/cjdk/cjdk/src/cjdk/_cache.py:138, in permanent_directory(prefix, key_url, fetchfunc, cache_dir, timeout_for_fetch_elsewhere)
136 with _create_key_tmpdir(cache_dir, key) as tmpdir:
137 if tmpdir:
--> 138 fetchfunc(tmpdir)
139 _move_in_fetched_directory(keydir, tmpdir)
140 _add_url_file(keydir, key_url)
File ~/work/cjdk/cjdk/src/cjdk/_install.py:42, in install_dir.<locals>.fetch(destdir)
40 def fetch(destdir):
41 _print_progress_header(conf, name)
---> 42 _download.download_and_extract(
43 destdir,
44 url,
45 checkfunc=checkfunc,
46 progress=conf.progress,
47 _allow_insecure_for_testing=conf._allow_insecure_for_testing,
48 )
File ~/work/cjdk/cjdk/src/cjdk/_download.py:52, in download_and_extract(destdir, url, checkfunc, progress, _allow_insecure_for_testing)
50 with tempfile.TemporaryDirectory(prefix="cjdk-") as tempd:
51 file = Path(tempd) / f"archive.{ext}"
---> 52 download_file(
53 file,
54 url,
55 checkfunc=checkfunc,
56 progress=progress,
57 _allow_insecure_for_testing=_allow_insecure_for_testing,
58 )
59 extract(destdir, file, progress)
File ~/work/cjdk/cjdk/src/cjdk/_download.py:83, in download_file(dest, url, checkfunc, progress, _allow_insecure_for_testing)
78 raise NotImplementedError(
79 f"Cannot handle {scheme} (must be https)"
80 )
82 response = requests.get(url, stream=True)
---> 83 response.raise_for_status()
84 total = response.headers.get("content-length", None)
85 total = int(total) if total else None
File ~/work/cjdk/cjdk/.nox/docs/lib/python3.14/site-packages/requests/models.py:1026, in Response.raise_for_status(self)
1021 http_error_msg = (
1022 f"{self.status_code} Server Error: {reason} for url: {self.url}"
1023 )
1025 if http_error_msg:
-> 1026 raise HTTPError(http_error_msg, response=self)
HTTPError: 404 Client Error: Not Found for url: https://dlcdn.apache.org/maven/maven-3/3.9.6/binaries/apache-maven-3.9.6-bin.tar.gz
The Maven .tar.gz file has been extracted into maven_dir; find the bin
directory within it:
maven_bin = list(maven_dir.glob("apache-maven-*"))[0] / "bin"
assert (maven_bin / "mvn").is_file()
Let’s write a context manager that we can use to temporarily put the Maven
bin directory on PATH.
@contextmanager
def path_prepended(path):
"""
Context manager to temporarily prepend the given path to PATH.
"""
save_path = os.environ.get("PATH", "")
new_path = str(path) + os.pathsep + save_path
os.environ["PATH"] = new_path
try:
yield
finally:
os.environ["PATH"] = save_path
Now for the magic: run a program by specifying its Maven coordinates.
The JRE and all required Jars are downloaded (and cached) automatically.
with cjdk.java_env(vendor="zulu-jre", version="8"):
with path_prepended(maven_bin):
jgo.main_from_endpoint(
"com.puppycrawl.tools:checkstyle:9.3",
primary_endpoint_main_class="com.puppycrawl.tools.checkstyle.Main",
argv=["--version"],
)