By Greg Nowak. Updated 17 October 2026.
A missing report email can leave an operations team checking dashboards manually or an agency chasing a client delivery. When the underlying script uses mailR, the failure may happen before it reaches the mail server.
mailR depends on rJava, which connects R to Java. If that connection breaks after an upgrade or migration, changing SMTP passwords will not help. The practical approach is to check Java, repair R’s configuration, and then test the complete job under its normal schedule.
Start with the error, then follow the right layer
This familiar message means the process cannot load Java’s virtual machine library:
libjvm.so: cannot open shared object file: No such file or directoryFor a system R installation, the usual repair is sudo R CMD javareconf. Before running it, confirm which R installation and Java development kit the job actually uses.
| What you see | Where to investigate | Next step |
|---|---|---|
java or javac is missing |
Java installation | Install the appropriate JDK |
libjvm.so cannot be loaded |
Java library paths | Check the selected JDK and reconfigure R |
rJava installation fails |
Build environment | Read the first configuration or compiler error |
| Works manually, fails on schedule | Job environment | Check the account, R binary, library and working directory |
| Java loads, but sending fails | Email connection | Check SMTP settings, authentication and network access |
1. Check Java and the R installation
Run these checks on the machine or inside the container that executes the report:
command -v R Rscript
java -version
javac -version
readlink -f "$(command -v java)"java checks the runtime; javac checks the compiler supplied by a Java Development Kit. Building rJava from source requires a JDK, rather than just a runtime.
If no suitable JDK is installed, Ubuntu’s documentation provides this command for the default JDK for your Ubuntu release:
sudo apt update
sudo apt install default-jdkFor an established application, keep its tested Java version where possible. Installing another JDK does not prove that R will select it.
2. Reconfigure the R installation used by the job
The R administration manual explains that Java upgrades can leave stored library paths needing an update. Run the following as the owner of the R installation; use sudo when that owner is root:
sudo R CMD javareconfIf production uses a different R binary, supply its absolute path. Read the output for failed checks before continuing.
With several JDKs installed, inspect the available directories and explicitly select the intended one. Replace the example path below with a verified JDK directory:
ls -la /usr/lib/jvm
sudo env JAVA_HOME=/absolute/path/to/installed-jdk R CMD javareconfThis changes configuration shared by processes using that R installation. Coordinate the repair if other applications depend on it.
3. Test rJava before rebuilding it
Start a fresh R process and test the bridge independently of email:
Rscript -e 'library(rJava); .jinit(); cat("Java bridge OK\n")'
Rscript -e 'print(.libPaths()); print(find.package("rJava"))'The second command shows which package installation R finds. That matters when an administrator and a reporting account use different libraries.
If loading still fails and the package needs rebuilding, use the production project’s package management process. For a conventional CRAN installation, run this through the intended R installation and account, with a writable target library:
Rscript -e 'install.packages("rJava", repos="https://cloud.r-project.org")'Source installation also needs build tools, including a C compiler and GNU make. If installation fails, inspect the first meaningful error rather than repeatedly reinstalling. The rJava documentation describes its requirements and Java initialization functions.
4. Prove the scheduled job works
A successful SSH test is a useful checkpoint. The repair is complete when the reporting job succeeds in its actual execution environment.
As an initial check, run the bridge test as the production account. Replace report-runner and the Rscript path with the real values:
sudo -u report-runner -H /usr/bin/Rscript -e 'library(rJava); .jinit(); cat("Java bridge OK\n")'This checks the account, but does not reproduce every cron or systemd setting. Follow it with a controlled execution through the actual scheduler. Check package libraries, attachment paths, permissions and the working directory.
If a Java library path override is necessary, R supports R_JAVA_LD_LIBRARY_PATH, but it must be supplied before R starts; putting it in ~/.Renviron is too late. Prefer a documented configuration repair over a global library-path workaround.
5. Test email delivery and leave a useful handover
Once Java loads, send a small test message to a controlled recipient. The mailR README documents debug = TRUE for detailed diagnostics. Enable it temporarily and review the SMTP response alongside the provider’s current connection and authentication requirements. Treat debug logs as potentially sensitive.
Keep credentials outside the script. Make failed sends produce a useful log and a failing job status, with monitoring independent of the broken email channel. Confirm receipt and attachment contents before rerunning a client delivery, and check whether a previous attempt already sent anything.
Repair the workflow or replace mailR?
As of this update, CRAN lists mailR 0.8, published in December 2021. Its age warrants a maintenance review, but does not by itself justify replacing a working workflow.
For an existing report, repair may be the least disruptive option. For new automation, compare Java maintenance, supported authentication, delivery tracking and ownership with a Java-free mail library or an email API.
If reporting failures are taking time from your team, Greg can help diagnose the workflow, verify scheduled delivery and document the setup so the next person can maintain it.
Related on GrN.dk
- Sending Mail from a Linux Server with Postfix: A Reliable SMTP Relay Setup
- Nginx 1.30 Changed Upstream Connections: What to Test Before You Upgrade
- Drupal Deployments: Keep Small Fixes From Rewriting Live Settings
Need help with this kind of work?
Get help with your R reporting workflow Get in touch with Greg.