In a previous question I asked how to compile R to load it in java using JNI. Compiling libR (from the R statistical package) as a standalone C library for java+jni . Now I can load the libR in java but I get the following R error:

##Trying load RSession
##LOADED !! RSession
RSession.c:Java_RSession_test:15
RSession.c:Java_RSession_initEmbeddedR:21
[0] /path/to/TMP/R-4.3.2/bin/R
[1] --vanilla
[2] --quiet
[3] --encoding=UTF-8
[4] --no-init-file
[5] --no-readline
RSession.c:Java_RSession_initEmbeddedR:35
Error: C stack usage  134897775332 is too close to the limit
Error: C stack usage  134897775380 is too close to the limit
Error: C stack usage  134897775268 is too close to the limit
Fatal error: unable to initialize the JIT

I put a minimal code to reproduce below:

As far as I understand the is a kind of recursion at the R level but I don't know where. There is no .Renviron, .Rprofile, etc in my HOME.


java code:

public class RSession {
    // Déclaration des fonctions natives
    public static native int initEmbeddedR(int argc, String[] argv);
    public static native void endEmbeddedR(int fatal);
    public static native void test();

    public static void main(String[] args) throws Throwable {

        final String R_HOME = System.getenv("R_HOME");
            if(R_HOME==null || R_HOME.isEmpty()) {
                System.err.println("undefined R_HOME");
                System.exit(-1);
                }

        final String libName= "RSession";
        System.err.println("##Trying load "+libName);
        try {
            System.loadLibrary(libName);
            }
        catch(Throwable err) {
            System.err.println("##Cannot load "+libName);
            err.printStackTrace();
            System.exit(-1);
            }
        System.err.println("##LOADED !! "+libName);

        test();
        String[] argv = {args[0],"--vanilla","--quiet","--encoding=UTF-8","--no-init-file","--no-readline"};
        
        int result = RSession.initEmbeddedR(argv.length, argv);
        System.out.println("initEmbeddedR returned result: " + result);

        RSession.endEmbeddedR(0);
        System.out.println("endEmbeddedR called successfully");
    }
}

the following C code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Rinternals.h>
#include <Rembedded.h>
#include <R_ext/Parse.h>

#include <jni.h>
#include "RSession.h"

#define WHERE fprintf(stderr,"%s:%s:%d\n",__FILE__,__FUNCTION__,__LINE__)

JNIEXPORT void JNICALL Java_RSession_test
  (JNIEnv * env, jclass clazz) {
    WHERE;
   }



JNIEXPORT jint JNICALL Java_RSession_initEmbeddedR(JNIEnv *env, jobject obj, jint argc, jobjectArray argv) {
    WHERE;
    int i;
    int len = (*env)->GetArrayLength(env, argv);
    char **args = (char **)malloc(len * sizeof(char *));
    for (i = 0; i < len; i++) {
        jstring string = (jstring)(*env)->GetObjectArrayElement(env, argv, i);
        const char *rawString = (*env)->GetStringUTFChars(env, string, 0);
        args[i] = strdup(rawString);
         fprintf(stderr,"[%d] %s\n",i,args[i]);
        (*env)->ReleaseStringUTFChars(env, string, rawString);
    }

        WHERE;

    int result = Rf_initEmbeddedR(argc, args);
    WHERE;

    // Libère la mémoire allouée pour les chaînes C
    for (i = 0; i < len; i++) {
        free(args[i]);
    }
    free(args);
    WHERE;
    return result;
}

JNIEXPORT void JNICALL Java_RSession_endEmbeddedR(JNIEnv *env, jobject obj, jint fatal) {
    // Appelle la fonction C
    WHERE;
    Rf_endEmbeddedR(fatal);
    WHERE;
}

and compiled and invoked with the following makefile:

SHELL=/bin/bash
CC=gcc
R_VERSION=4.3.2

test: TMP/RSession.class  TMP/libRSession.so
    echo | R_HOME=${PWD}/TMP/lib/R PATH=$${PATH}:{PWD}/TMP/R-$(R_VERSION)/bin  java -Djava.library.path=${PWD}/TMP:TMP/R-$(R_VERSION)/lib -cp TMP RSession "${PWD}/TMP/R-$(R_VERSION)/bin/R"

TMP/libRSession.so : RSession.c TMP/R-$(R_VERSION)/lib/libR.so TMP/RSession.h
    $(CC)  -ITMP -I$${JAVA_HOME}/include/ -I$${JAVA_HOME}/include/linux \
        -LTMP/R-$(R_VERSION)/lib `TMP/R-$(R_VERSION)/bin/R CMD config --cppflags` -shared -fPIC -o $@  -g $< -lR


TMP/RSession.h : TMP/RSession.class
    touch -c $@

TMP/RSession.class : RSession.java
    mkdir -p TMP
    javac -h TMP -d TMP $<
    touch $@

TMP/R-$(R_VERSION)/lib/libR.so :
    rm -rvf  "TMP/R-$(R_VERSION)" TMP/jeter.tar.gz
    mkdir -p $(dir $@)
    wget -O TMP/jeter.tar.gz "https://pbil.univ-lyon1.fr/CRAN/src/base/R-4/R-$(R_VERSION).tar.gz"
    (cd TMP && tar xfz jeter.tar.gz && rm jeter.tar.gz &&  cd R-$(R_VERSION) &&  ./configure --with-pcre1 --enable-R-shlib --with-x=no --prefix=${PWD}/TMP && make && make install)
0

There are 0 best solutions below