Multiple Java environments in one project with targets and callr

If you need to use multiple Java distribution versions in a single project, you can use a handy shortcut function use_java() kindly suggested by Hadley Wickham.

Essentialy, use_java() does the same thing as java_quick_install(), but in a less intrusive way. It downloads the distribution of the user requested major version of Java, unpacks it, also to the cache folder, but unlike java_quick_install(), it does not copy or link the Java installation folder from cache into the project directory and does not create or edit your .Rprofile file. Instead, it just sets the environment in the current R script to the requested Java binaries in the cache folder. The download and unpacking only happens once, so each next run is practically instant, as the function only needs to set the environment in the current R script.

How to use use_java()

Let’s illustrate this with a simple example.

First, load the package and check the valid major versions of Java:

library(rJavaEnv)
getOption("rJavaEnv.valid_major_java_versions")
[1] "8"  "11" "17" "21" "22"

Now select any two or three versions and run use_java(), checking every time that correct java was set in the current environment.

use_java("8")
"8" == java_check_version_cmd(quiet = TRUE)
"8" == java_check_version_rjava(quiet = TRUE)
[1] TRUE
[1] TRUE
use_java(17)
"17" == java_check_version_cmd(quiet = TRUE)
"17" == java_check_version_rjava(quiet = TRUE)
[1] TRUE
[1] TRUE
use_java(21)
"21" == java_check_version_cmd(quiet = TRUE)
"21" == java_check_version_rjava(quiet = TRUE)
[1] TRUE
[1] TRUE

You probably had to wait for a bit for the Java distribution to be downloaded and unpacked.

However, now if you repeat the same commands, you will see that the correct Java version is set instantly, as downloading and unpacking are skipped.

How to use with targets and callr

Both {targets} and {callr} packages allow the user to run any R scripts in clean separate R sessions. This essentially allows the user to run multiple versions of Java in one project with targets and callr, mostly overcoming the issue of manually switching between Java versions in one project.

One simple thing you can do if one of the scripts needs Java 8, and another one needs Java 17, is to insert use_java() in beginning of the scripts that you run through targets or callr like so:

library(rJavaEnv)
use_java("17")

Or:

rJavaEnv::use_java("17")

The first run of such script will have to go through the the process of downloading and unpacking the Java distribution. The second run will not need to download and unpacking and will be instant.

If you need the runs to be instant from the first attempt, you can predownload and pre-install Java into cache folders using:

java_17_distrib <- java_download("17")
java_unpack(java_17_distrib)