Quickly install Java Development Kit (JDK) without administrative
privileges and set environment variables in current R session or project
to solve common issues with ‘Java’ environment management in ‘R’.
Recommended to users of Java/{rJava}-dependent R packages such as
{r5r}, {opentripplanner}, {xlsx}, {openNLP}, {rWeka},
{RJDBC}, {tabulapdf}, and many more. {rJavaEnv} prevents common
problems like Java not found, Java version conflicts, missing Java
installations, and the inability to install Java due to lack of
administrative privileges. {rJavaEnv} automates the download,
installation, and setup of the Java on a per-project basis by setting
the relevant JAVA_HOME in the current R session or the current
working directory (via .Rprofile, with the user’s consent). Similar to
what {renv} does for R packages, {rJavaEnv} allows different
Java versions to be used across different projects, but can also be
configured to allow multiple versions within the same project (e.g. with
the help of {targets} package). For users who need to install
{rJava} or other Java-dependent packages from source, {rJavaEnv}
will display a message with instructions on how to run
R CMD javareconf to make the Java configuration permanent, but also
provides a function java_build_env_set() that sets the environment
variables in the current R session temporarily to allow installation of
{rJava} from source without R CMD javareconf. On Linux, in addition
to setting environment variables, {rJavaEnv} also dynamically loads
libjvm.so to ensure {rJava} works correctly. See
documentation
for more details.
Install from CRAN:
install.packages('rJavaEnv')
Install the development version
Install the latest release development version from R-multiverse:
install.packages('rJavaEnv',
repos = c('https://community.r-multiverse.org', 'https://cloud.r-project.org')
)You can also install the development version of rJavaEnv directly from
GitHub:
if (!requireNamespace("remotes", quietly = TRUE)) {
install.packages("remotes")
}
remotes::install_github("e-kotov/rJavaEnv", force = TRUE)rJavaEnv::java_quick_install(version = 21)This will:
-
download
Java21 distribution compatible with the current operating system and processor architecture into a local cache folder; -
extract the downloaded
Javadistribution into another cache folder; -
create a symbolic link (for macOS and Linux) or junction (for Windows, if that fails, just copies the files) rjavaenv/
platform/processor_architecture/distribution/backend/java_versionin the current directory/project to point to the cached installation; -
set the current session’s
JAVA_HOMEandPATHenvironment variables to point to the installed (symlinked)Javadistribution; -
add code to
.Rprofilefile in the current directory/project to setJAVA_HOMEandPATHenvironment variables when the project is opened in RStudio.
As part of normal operation, rJavaEnv will update the JAVA_HOME and
PATH environment variables in the current R session, the local cache
in your R package library, and the .Rprofile file in the
project/current working directory. In line with CRAN
policies,
explicit user consent is required before making these changes.
Therefore, the first time you run any function from rJavaEnv that
makes such changes, you will be asked for consent. To explicitly consent
and/or to prevent interruptions in non-interactive mode, you can use the
rje_consent() function:
rje_consent(provided = TRUE)You can also specify a distribution different from the default “Corretto” (supported: “Corretto”, “Temurin” and “Zulu”), a specific version, or the SDKMAN download backend:
rJavaEnv::java_quick_install(version = 17, distribution = "Temurin")
rJavaEnv::java_quick_install(version = "21.0.9", distribution = "Zulu")
rJavaEnv::java_quick_install(version = 21, backend = "sdkman")The default "native" backend downloads from vendor APIs and verifies
SHA-256 checksums. The "sdkman" backend offers more builds but cannot
verify checksums. Use java_list_available() to see what can be
installed.
java_ensure() uses an already active or installed Java when it
satisfies the requirement and downloads one only when needed:
rJavaEnv::java_ensure(version = 21, type = "min")For rJava-dependent packages, call it before loading rJava or any
package that imports it. For packages that call Java on the command
line, local_java_env() and with_java_env() set Java for a single
function or block and restore the environment afterwards. See the
developer
vignette
for integration patterns.
Just insert this line at the top of any script that you run with
targets or callr:
rJavaEnv::use_java("21")This acts exactly like java_quick_install(), but only sets the
environment variables in the current session and does not copy or link
Java binaries into the project directory.
More details are in the vignette Multiple Java environments in one
project with targets and
callr.
If you do not want to use rJavaEnv anymore, please clear the cache
folders before removing the package:
java_clear_project(delete_all = TRUE)
java_clear_installed(delete_all = TRUE)
java_clear_distrib(delete_all = TRUE)Also, clear the .Rprofile file in the projects there you used the
package:
java_env_unset()The package has several core functions:
-
java_quick_install()- Downloads, installs, and sets Java environment in the current working/project directory, all in one line of code.
-
java_check_version_cmd()- Checks the installed Java version using terminal commands. For
packages like
opentripplanner, that performs Java calls using command line.
- Checks the installed Java version using terminal commands. For
packages like
-
java_check_version_rjava()- Checks the installed
Javaversion usingrJavain a separate R session. ForrJava-dependent packages such asr5r.
- Checks the installed
-
java_download()- Downloads a specified version and distribution of
Java.
- Downloads a specified version and distribution of
-
java_install()- Installs a
Javadistribution file into current (or user-specified) project directory.
- Installs a
-
java_env_set()- Sets the
JAVA_HOMEandPATHenvironment variables to a given path in current R session and/or in the.Rprofilefile in the project directory.
- Sets the
-
java_env_unset()- Removes the
JAVA_HOMEandPATHenvironment variables from the.Rprofilefile in the project directory (but not in the current R session, please restart the session so that R picks up the system Java).
- Removes the
-
java_list_*()(java_list_project(),java_list_installed(),java_list_distrib())- Lists all or some
Javaversions linked in the current project (or cached distributions or installations).
- Lists all or some
-
java_clear_*()(java_clear_project(),java_clear_installed(),java_clear_distrib())- Removes all or some
Javaversions linked in the current project (or cached distributions or installations).
- Removes all or some
-
java_valid_versions()- Lists all valid major
Javaversions that can be downloaded and installed for either current automatically detected OS and CPU architecture or user-specified platform and architecture.
- Lists all valid major
-
java_list_available()- Lists all installable Java versions from supported backends (native vendor APIs or SDKMAN). Supports filtering by platform and architecture.
-
use_java()- Same as
java_quick_install(), but in a less intrusive way. Does not copy or link theJavainstallation folder from cache into the project directory and does not create or edit your.Rprofilefile. Only sets requested java in the current R session.
- Same as
-
java_build_env_set()(andjava_build_env_unset())- Similar to
java_env_set(), but specifically designed for settingJavaenvironment variables for buildingrJavafrom source.
- Similar to
-
java_ensure()- Makes sure that a required
Javaversion (exact or minimum) is active, using the current session, system installations, or therJavaEnvcache before downloading anything.
- Makes sure that a required
-
java_resolve()- Finds or installs a required
Javaversion and returns itsJAVA_HOMEpath without changing environment variables.
- Finds or installs a required
-
local_java_env(),with_java_env()andwith_rjava_env()- Use a
Javaversion for the current scope or a block of code (command-lineJava), or run anrJavafunction in a separate R process with a givenJavaversion.
- Use a
-
java_check_compatibility()- Checks whether an already running
rJavaJVM meets a version requirement, without loadingrJavaor starting a JVM.
- Checks whether an already running
-
java_find_system()andjava_get_home()- List
Javainstallations found on the system, and return the currentJAVA_HOME.
- List
See more details on all the functions in the Reference.
For detailed usage, see the Quick Start Vignette.
A major version such as 21 installs the latest release of that major
version. For reproducibility, request a specific version such as
"21.0.9". java_resolve() and the functions built on it
(java_ensure(), local_java_env(), with_java_env() and
with_rjava_env()) then check the full runtime version of active,
system, cached and newly installed Java, and do not use a release that
does not match. If no matching release can be installed, java_ensure()
returns FALSE and the others report an error. The convenience helpers
java_quick_install() and use_java(), like java_download() and
java_install(), request the release from the vendor backend but do not
check the installed runtime, and the native Zulu backend may return
another release of the same major version. SDKMAN catalogues can lag
behind vendor releases.
The main limitation is that if you want to switch to another Java
environment for rJava, you will most likely have to restart the
current R session and set the JAVA_HOME and PATH environment
variables to the desired Java environment using
rJavaEnv::java_env_set(). This cannot be done dynamically within the
same R session due to the way Java is initialized in R, particularly
with the rJava-dependent packages such as
r5r. With the released rJava, loading
the rJava namespace (for example, by loading a package that imports
it) can lock the JVM library path even before the JVM starts, so
configure Java before that point. java_ensure() refuses to change
Java once it can no longer take effect for rJava. With packages like
opentripplanner, that performs Java
calls using command line, you can switch Java environments dynamically
within the same R session as much as you want.
Therefore, if you need to use R packages that depend on different Java
versions within the same project, you will have to create separate R
scripts for each Java environment and run them in separate R sessions.
One effective way of doing this is to use the
callr package to run R scripts in
separate R sessions. Another option is to use the
targets package to manage the whole
project workflow, which, as a side effect, will lead to all R scripts
being run in separate R sessions. To use rJavaEnv with targets, you
will need to download and install several Java environments using
rJavaEnv::java_download() and rJavaEnv::java_install() and set the
relevant path with rJavaEnv::java_env_set() at the beginning of each
function that requires a certain Java version.
rJavaEnv also has experimental, optional support for rJava builds
with deferred JVM loading, which are not part of released rJava. When
such a build reports that no JVM has been loaded yet, java_ensure()
can still select Java after the rJava namespace has loaded. Nothing
in rJavaEnv requires these builds; see the developer
vignette
for details.
rJavaEnv is recommended by several R packages and educational
resources to help users easily set up their Java environment:
-
{r5r}: Recommended in their README as the easiest way to install JDK.
-
{rTASSEL}: Recommended in their installation instructions to automate R-to-Java setup.
-
{causalDisco}: Recommended in their README and vignettes for simpler Java configuration.
-
{photon}: Recommends
rJavaEnvdynamically in startup and warning messages when Java is missing or has the wrong version. -
{r5rgui}: Recommended in their setup instructions.
-
Intro to Transport Accessibility Book (ipeaGIT)
-
EIT Urban Mobility Courses (EITbraga, PGmob360)
The future work includes:
-
Add support for more
Javadistributions -
Take care of
R CMD javareconf -
Possibly allow downloading several
Javadistributions in one function call, e.g. different major versions of the same ‘flavour’ or different ‘flavours’ of the same major version -
Possibly add automation to get the
Javathat is required by specificJava-dependent R packages
I am open to suggestions and contributions, welcome to issues and pull requests.
I thank rOpenSci for the Dev Guide, as well as Hadley Wickham and Jennifer Bryan for the R Packages book.
Package hex sticker logo is partially generated by DALL-E by OpenAI. The logo also contains the original R logo.
To cite package ‘rJavaEnv’ in publications use:
Kotov E, Chan C (2024). rJavaEnv: Java Environments for R Projects. doi:10.32614/CRAN.package.rJavaEnv https://doi.org/10.32614/CRAN.package.rJavaEnv. https://github.com/e-kotov/rJavaEnv.
BibTeX:
@Manual{rjavaenv,
title = {rJavaEnv: Java Environments for R Projects},
author = {Egor Kotov and Chung-hong Chan},
year = {2024},
url = {https://github.com/e-kotov/rJavaEnv},
doi = {10.32614/CRAN.package.rJavaEnv},
}
