Skip to content

JRI: don't System.exit on native load failure; fix double assign truncation - #2

Open
pvitt72 wants to merge 2 commits into
s-u:masterfrom
pvitt72:fix/jri-rengine-no-system-exit
Open

JRI: don't System.exit on native load failure; fix double assign truncation#2
pvitt72 wants to merge 2 commits into
s-u:masterfrom
pvitt72:fix/jri-rengine-no-system-exit

Conversation

@pvitt72

@pvitt72 pvitt72 commented Jun 30, 2026

Copy link
Copy Markdown

Motivation

When the JRI native library cannot be loaded, org.rosuda.JRI.Rengine's static initializer calls System.exit(1). This terminates the entire JVM, which is fatal when JRI is embedded in a container (application server, plugin host, another long-lived app). The caller has no chance to recover or report the error.

Changes

rosuda/JRI/Rengine.java:

  1. Remove System.exit(1) from the static initializer. On UnsatisfiedLinkError it still logs the diagnostic and leaves jriLoaded == false (the existing, documented flag). The jri.ignore.ule property path is unchanged.
  2. Guard both Rengine constructors: if !jriLoaded they throw an UnsatisfiedLinkError instead of proceeding (which previously failed later, on the R thread). UnsatisfiedLinkError keeps source/binary compatibility with callers already catching it from native calls. The high-level REngine/JRI/JRIEngine already checks Rengine.jriLoaded and throws REngineException, so the canonical path is fully recoverable.
  3. Fix assign(String, REXP) for double scalars: the XT_DOUBLE branch called Double.intValue() instead of doubleValue(), truncating the value to an integer before assigning it to R (e.g. assign("x", new REXP(3.7)) assigned 3.0). The adjacent int branch already uses intValue() correctly.

Stand-alone applications that relied on the previous exit-on-failure behavior can check Rengine.jriLoaded (or catch the constructor's UnsatisfiedLinkError).

🤖 Generated with Claude Code

pvitt72 and others added 2 commits June 30, 2026 20:06
…cation

The Rengine static initializer called System.exit(1) when the JRI native
library failed to load. This kills the whole JVM, which is fatal when JRI
is embedded in a container (application server, plugin host, ...). Leave
jriLoaded == false instead and have both Rengine constructors throw an
UnsatisfiedLinkError so callers can handle the failure.

Also fix assign(String, REXP) for double scalars: it called Double.intValue()
instead of doubleValue(), truncating the value to an integer before assigning
it to R.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Modern JDKs (9+) reject -source/-target 1.4, so a plain 'make' failed with
'Source option 1.4 is no longer supported'. Default JDKVER to 8, the oldest
level still accepted, and document that 14+ must not be used for JRI.jar
because 'yield' becomes a reserved identifier there.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant