-
Notifications
You must be signed in to change notification settings - Fork 4
Open
Labels
Description
Background / Motivation
A developer or user of loadeR.java may eventually need to run with different netCDF-Java setups without editing the package code:
- In production, use a single JAR (e.g.,
netcdfAll-*.jar). - In development, point to class directories and/or multiple JARs (e.g., Gradle
build/classes/java/main,build/resources/main, plus deps). - In packaged installs, if nothing is configured, just use JAR bundle with the R package.
Right now, switching between these scenarios requires modifying the package or copying JARs into the repo. A small, standard initialization hook would cover all cases cleanly.
Proposed Behaviour (non-breaking)
loadeR.java should determine the Java classpath for netCDF-Java at startup using this precedence:
- R option:
loadeR.netcdf_java_classpath - Environment variable:
LOADER_NETCDF_JAVA_CLASSPATH - Bundled fallback: package directory
java/(include directories and JARs in the classpath)
Both the option and env var accept a classpath string: one or many entries, directories and/or JARs, separated by the platform path separator (: on Linux/macOS, ; on Windows).
Why this approach
- Mirrors standard JVM usage (explicit
-cpsemantics). - Avoids hardcoding a specific artifact (e.g.,
netcdfAll) and works equally well for ToolsUI fat jars or module class dirs. - Keeps the current default (bundled jars) working for users who don’t configure anything.
User-facing Configuration (examples)
Production (single JAR)
# Session override
options(loadeR.netcdf_java_classpath = "/opt/netcdf-java/netcdfAll-5.9.0.jar")
library(loadeR.java)Development (directories + jars)
options(loadeR.netcdf_java_classpath = paste(
"~/dev/netcdf-java/cdm/build/classes/java/main",
"~/dev/netcdf-java/cdm/build/resources/main",
"~/dev/netcdf-java/grib/build/classes/java/main",
"~/dev/netcdf-java/grib/build/resources/main",
sep = .Platform$path.sep
))
library(loadeR.java)Environment variable (persistent, default)
# Linux/macOS
export LOADER_NETCDF_JAVA_CLASSPATH="/opt/netcdf-java/lib/*"
R -q -e "library(loadeR.java)"
# Windows PowerShell
$env:LOADER_NETCDF_JAVA_CLASSPATH = "C:\netcdf-java\lib\*"
R -NoSave -e "library(loadeR.java)"Bundled fallback (no config)
- Drop any required jars and directory into
java/.
Expected Startup Messages
- Print which source was used:
netCDF-Java CLASSPATH from R option loadeR.netcdf_java_classpath: ...netCDF-Java CLASSPATH from env LOADER_NETCDF_JAVA_CLASSPATH: ...netCDF-Java CLASSPATH from bundled inst/java/*: ...
Implementation Notes (sketch, not a full rewrite)
- In
.onLoad():- Read
getOption("loadeR.netcdf_java_classpath", "")andSys.getenv("LOADER_NETCDF_JAVA_CLASSPATH", ""). - Split by
.Platform$path.sep. - If both option and env are set and differ, option wins; consider warning (or
loadeR.java.strict_classpathto error). - Fallback:
file.path(system.file("java", package = pkgname), "*"). - Initialize JVM via
rJava::.jinit(classpath = classpath, parameters = ...).
- Read
- In
.onAttach():- Optionally report detected netCDF-Java runtime version via
Package.getImplementationVersion()when available; otherwise print a friendly “version unknown/dev” message when using dirs/wildcards.
- Optionally report detected netCDF-Java runtime version via
Tests (suggested)
- Option supplies two directories → both present in
.jclassPath(). - Env var supplies wildcard dir → jars are available (verify a known class loads).
- Neither option nor env set → classpath contains one entry ending in
inst/java/*. - Already-initialized JVM → entries added, wildcard warning printed.
- Windows path separator (
;) works as expected.
Documentation snippet (README)
#### Selecting netCDF-Java at startup
`loadeR.java` looks for a netCDF-Java classpath in this order:
1. `options(loadeR.netcdf_java_classpath)`
2. `LOADER_NETCDF_JAVA_CLASSPATH` (env var)
3. All jars under the package’s `inst/java/` (`inst/java/*`)
The classpath may contain one or more directories and/or JARs separated by the platform path separator (`:` on Linux/macOS, `;` on Windows). Wildcards like `.../lib/*` are supported and are expanded by the JVM at startup. Example:
```r
options(loadeR.netcdf_java_classpath = "/opt/netcdf-java/lib/*")
library(loadeR.java)
```