Download JDK or JRE distributions on the fly
Project description
cjdk
cjdk (for "cached JDK") is a Python package and command-line tool to download and run JDK (Java Development Kit) or JRE (Java Runtime Environment) distributions.
The required environment (JAVA_HOME
and PATH
) can be set up automatically
for the requested JDK, which is downloaded as needed and stored (by default) in
a per-user cache directory.
What for
- Installing exact JDK versions for reproducible testing
- Working with multiple versions of JDKs
- Deploying tools that require Java
For example, you might want to set JAVA_HOME
to a JDK 8 installation while
working on a particular project that supports that version, but you might also
want to be able to run tools written in Java, and some of those may require a
newer version of Java (say, 11). Without having to manually set JAVA_HOME
every time, you can invoke a tool (say, CheckStyle)
like this:
cjdk --jdk=11+ exec java -jar checkstyle-10.3-all.jar -c style.xml path/to/file.java
(or even leave out the --jdk=11+
outside of automation).
cjdk will automatically install the latest Temurin JDK (see how to
override) and invoke its java
with JAVA_HOME
set to the
correct directory. The download will only happen when the latest JDK has not
yet been installed by cjdk.
The ability to use simple commands to use a particular JDK, whether or not it is already available on the system, makes it easy to manage and share test environments and build tooling (such as Git hooks).
cjdk was inspired by Coursier's
java
subcommand (and depends on
Coursier's JDK index). Unlike Coursier, cjdk does not require
a Java runtime to bootstrap.
Requirements
cjdk is a pure-Python package. No pre-installed JDK or JRE is required. Python 3.8 or later is required.
Installing
pip install cjdk
This installs the cjdk
Python package and the cjdk
command-line tool.
As usual, make sure you are using the right pip
for your Python installation;
use of a virtual environment is recommended.
Command line interface
Usage can be viewed with cjdk --help
. Subcommand usage can be viewed
similarly; for example, cjdk exec --help
.
There are currently 2 subcommands: java-home
and exec
.
$ cjdk --jdk temurin:17 java-home
cjdk: Installing JDK: temurin:1.17.0.3
cjdk: Destination: /Users/mark/Library/Caches/cjdk
Downloading: 100%|███████████████████████████| 177M/177M [00:06<00:00, 27.8MB/s]
Extracting: 545files [00:01, 443.48files/s]
/Users/mark/Library/Caches/cjdk/v0/jdks/9c70ad108f233bbbba06d095beaa8580f93d3cd3/jdk-17.0.3+7/Contents/Home
This downloads (if necessary) the latest Temurin JDK 17 and prints the path
that is suitable as the value of JAVA_HOME
. (Note that the progress info is
printed to stderr, whereas the actual Java home directory is printed to
stdout.)
$ cjdk --jdk temurin:17 exec java -version
openjdk version "17.0.3" 2022-04-19
OpenJDK Runtime Environment Temurin-17.0.3+7 (build 17.0.3+7)
OpenJDK 64-Bit Server VM Temurin-17.0.3+7 (build 17.0.3+7, mixed mode)
This runs the program java
(with option -version
) after setting JAVA_HOME
and PATH
to point to the latest Temurin JDK 17 (which is downloaded if
necessary). The same works for any command, whether part of the JDK (such as
java
, javac
) or already on the path (for example, mvn
).
The --jdk
(or -j
for short) option takes a specifier consisting of a
vendor and version, both of which are
optional. See the sections below on those topics.
Other global options (which must be given before the subcommand) include
--no-progress
, to hide the progress bar when downloading, and --cache-dir
,
to override the location of the cache directory in which
JDKs are installed.
Python API
>>> import cjdk
>>> print(cjdk.java_home(vendor="temurin", version="17"))
/Users/mark/Library/Caches/cjdk/v0/jdks/9c70ad108f233bbbba06d095beaa8580f93d3cd3/jdk-17.0.3+7/Contents/Home
downloads (if necessary) the latest Temurin JDK 17 and prints the path that is
suitable as the value of JAVA_HOME
.
>>> import subprocess
>>> with cjdk.java_env(vendor="temurin", version="17"):
... subprocess.run(["java", "-version"])
...
openjdk version "17.0.3" 2022-04-19
OpenJDK Runtime Environment Temurin-17.0.3+7 (build 17.0.3+7)
OpenJDK 64-Bit Server VM Temurin-17.0.3+7 (build 17.0.3+7, mixed mode)
CompletedProcess(args=['java', '-version'], returncode=0)
runs the program java
(with option -version
) after setting JAVA_HOME
and
PATH
to point to the latest Temurin JDK 17 (which is downloaded if
necessary).
Both cjdk.java_home()
and cjdk.java_env()
take the following additional
keyword arguments:
vendor=
JDK vendor name.version=
JDK version expression.jdk=
Alternative way to specifyvendor:version
as a single string.progress=
If false, do not show progress bars when downloading.cache_dir=
Override the location of the cache directory in which JDKs are installed.index_url=
Override the location of the JDK index used to find JDKs.index_ttl=
Time to live for the cached JDK index; if set to 0, always download freshly.os=
Override operating system for the JDK (default: current OS)arch=
Override architecture for the JDK (default: current architecture)
In addition, cjdk.java_env()
takes an additional keyword argument,
add_bin=
(default: True
), which, if set to false, will skip modification of
PATH
.
Environment variables
The following environment variables modify the default behavior of both the CLI and the Python API, and are intended for setting user preferences:
CJDK_CACHE_DIR
: Set to an absolute path to override the default cache directory. Overrides on the command line or by keyword arguments take precedence over this environment variable.CJDK_DEFAULT_VENDOR
: Set to a vendor to change the default in case the vendor is not given on the command line or by keyword arguments. When this environment variable is unset, the default isadoptium
.
Cache directory
By default, cjdk uses the platform-dependent user cache directory to store downloaded JDKs and other data. The defaults are:
- On Linux,
~/.cache/cjdk
, or, if defined,$XDG_CACHE_HOME/cjdk
, - On macOS,
~/Library/Caches/cjdk
, and - On Windows,
%LOCALAPPDATA%\cjdk\cache
, which is usually%USERPROFILE%\AppData\Local\cjdk\cache
.
You can delete this directory at any time (provided that no program is running using a JDK installed by cjdk).
You can override the default cache directory by setting the environment
variable CJDK_CACHE_DIR
to the desired directory.
You can also override the cache directory by specifying the flag
--cache-dir=DIR
on the command line or giving the cache_dir=path
keyword
argument to most API functions. This takes precedence over CJDK_CACHE_DIR
and
is useful for scripts that want to maintain their own set of JDK installations.
JDK index
cjdk currently depends on the JDK index assembled (in an automated fashion) by the Coursier project.
The index is used to map JDK vendors and versions to download URLs.
A local copy of the index is stored in the cache directory, and a fresh copy is fetched if it is more than a day old.
JDK vendors
cjdk allows you to choose among JDKs and JREs released from different
sources. Names such as adoptium
, zulu-jre
, or graalvm-java17
are used to
select a particular series of JDKs. These names are referred to as "vendors",
even though they do not map 1:1 to companies.
If no vendor is specified, adoptium
is used by default, unless the
environment variable CJDK_DEFAULT_VENDOR
is defined, in which case its value
is used instead.
About concrete vendors
The available set of vendors is determined by the JDK index, and is not built into cjdk itself.
Common vendors include adopt
, adoptium
, temurin
, liberica
, zulu
, and
their JRE counterparts adopt-jre
, adoptium-jre
, temurin-jre
,
liberica-jre
, zulu-jre
.
AdoptOpenJDK was
succeeded
by Eclipse Temurin by Adoptium in 2021. To specifically get AdoptOpenJDK
releases, use adopt
; to specifically get Temurin releases, use temurin
;
adoptium
will get a Temurin release if available, falling back to
AdoptOpenJDK for older versions. (Again, this behavior is defined by the index,
not cjdk itself.)
For GraalVM, graalvm-java11
, graalvm-java16
, and graalvm-java17
are
available at the time of writing (these each have versions
that are numbered independently of the regular JDK version).
JDK versions
JDK versions are selected using version expressions attached to vendor names:
for example, temurin:17
or graalvm-java17:22.1.0
.
Like vendors, the available versions for a given vendor are determined by the JDK index. Different vendors use different numbering schemes.
If you want to reproducibly install an exact JDK build, you should consult the index and specify an exact version in full.
Otherwise, it is often sufficient to use a single number, such as 17
, to
specify the major version of the JDK. This will match to the latest version for
the given vendor that is at least 17 and less than 18.
You can also use 17+
to indicate the latest version, but no less than 17. If
no version is given, it is interpreted as 0+
, that is, the latest available
version with no minimum.
For the purpose of comparing and matching versions, any 1.
prefix is ignored,
except in the case where the vendor contains graalvm
. So adoptium:1.8
has
the same effect as adoptium:8
.
Dots .
and dashes -
are considered the same when comparing and matching
versions.
Development
Clone the Git repository and make sure to enable the Git hooks by running
pre-commit install
. You can install pre-commit
using pip
, brew
, and other means.
To run the tests (best done in a virtual environment),
pip install -e .[testing]
pytest
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file cjdk-0.1.1.tar.gz
.
File metadata
- Download URL: cjdk-0.1.1.tar.gz
- Upload date:
- Size: 20.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.1 CPython/3.9.13
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 47254f11e04f0116ff907216bb3ed38a89e65fda27fd07f1a8257077090b0f0e |
|
MD5 | 98ed1b20b7e7bd33408c52b658ada2fb |
|
BLAKE2b-256 | e813579cdeae549d36f6bc5f3d5030623bf78ff86bc7d9f019e2421c1212934a |
File details
Details for the file cjdk-0.1.1-py3-none-any.whl
.
File metadata
- Download URL: cjdk-0.1.1-py3-none-any.whl
- Upload date:
- Size: 19.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.1 CPython/3.9.13
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | f51799988147b75bcc800daf2692282bd9756df9d92dec77d7fc584686fd4a2e |
|
MD5 | e7f0a19ff26dc529f7817ce4a5b4602e |
|
BLAKE2b-256 | f50a2eb48fe40eb74c29414f093c8238537cd10742b5d11782211dcc634805c3 |