rJavaEnv: Java Environments for R Projects rJavaEnv website

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

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)

Simple Example

rJavaEnv::java_quick_install(version = 21)

This will:

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.

Ensuring a Java version in scripts and packages

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.

Using rJavaEnv with targets and callr

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.

Cleanup

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()

Functions Overview

The package has several core functions:

  1. java_quick_install()

    • Downloads, installs, and sets Java environment in the current working/project directory, all in one line of code.
  2. java_check_version_cmd()

    • Checks the installed Java version using terminal commands. For packages like opentripplanner, that performs Java calls using command line.
  3. java_check_version_rjava()

    • Checks the installed Java version using rJava in a separate R session. For rJava-dependent packages such as r5r.
  4. java_download()

    • Downloads a specified version and distribution of Java.
  5. java_install()

    • Installs a Java distribution file into current (or user-specified) project directory.
  6. java_env_set()

    • Sets the JAVA_HOME and PATH environment variables to a given path in current R session and/or in the .Rprofile file in the project directory.
  7. java_env_unset()

    • Removes the JAVA_HOME and PATH environment variables from the .Rprofile file in the project directory (but not in the current R session, please restart the session so that R picks up the system Java).
  8. java_list_*() (java_list_project(), java_list_installed(), java_list_distrib())

    • Lists all or some Java versions linked in the current project (or cached distributions or installations).
  9. java_clear_*() (java_clear_project(), java_clear_installed(), java_clear_distrib())

    • Removes all or some Java versions linked in the current project (or cached distributions or installations).
  10. java_valid_versions()

    • Lists all valid major Java versions that can be downloaded and installed for either current automatically detected OS and CPU architecture or user-specified platform and architecture.
  11. java_list_available()

    • Lists all installable Java versions from supported backends (native vendor APIs or SDKMAN). Supports filtering by platform and architecture.
  12. use_java()

    • Same as java_quick_install(), but in a less intrusive way. Does not copy or link the Java installation folder from cache into the project directory and does not create or edit your .Rprofile file. Only sets requested java in the current R session.
  13. java_build_env_set() (and java_build_env_unset())

    • Similar to java_env_set(), but specifically designed for setting Java environment variables for building rJava from source.
  14. java_ensure()

    • Makes sure that a required Java version (exact or minimum) is active, using the current session, system installations, or the rJavaEnv cache before downloading anything.
  15. java_resolve()

    • Finds or installs a required Java version and returns its JAVA_HOME path without changing environment variables.
  16. local_java_env(), with_java_env() and with_rjava_env()

    • Use a Java version for the current scope or a block of code (command-line Java), or run an rJava function in a separate R process with a given Java version.
  17. java_check_compatibility()

    • Checks whether an already running rJava JVM meets a version requirement, without loading rJava or starting a JVM.
  18. java_find_system() and java_get_home()

    • List Java installations found on the system, and return the current JAVA_HOME.

See more details on all the functions in the Reference.

For detailed usage, see the Quick Start Vignette.

Limitations

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.

Recommended by

rJavaEnv is recommended by several R packages and educational resources to help users easily set up their Java environment:

R Packages

Courses and Books

Future work

The future work includes:

I am open to suggestions and contributions, welcome to issues and pull requests.

Acknowledgements

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.

Citation

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},
}