@@ -9,6 +9,9 @@ JavaVM *jvm;
99/* this will be set when Java tries to exit() but we carry on */
1010int java_is_dead = 0 ;
1111
12+ /* current JVM state */
13+ int rJava_JVM_state = JVM_STATE_NONE ;
14+
1215/* cached, global objects */
1316
1417jclass javaStringClass ;
@@ -78,13 +81,20 @@ static int JNICALL vfprintf_hook(FILE *f, const char *fmt, va_list ap) {
7881static void JNICALL exit_hook (int status ) {
7982 /* REprintf("\nJava requested System.exit(%d), trying to raise R error - this may crash if Java is in a bad state.\n", status); */
8083 java_is_dead = 1 ;
84+ rJava_JVM_state = JVM_STATE_DEAD ;
8185 Rf_error ("Java called System.exit(%d) requesting R to quit - trying to recover" , status );
8286 /* FIXME: we could do something smart here such as running a call-back
8387 into R ... jump into R event loop ... at any rate we cannot return,
8488 but we don't want to kill R ... */
8589 exit (status );
8690}
8791
92+ int existingJVMs () {
93+ jsize vms = 0 ;
94+ JavaVM * jvms [32 ];
95+ return (JNI_GetCreatedJavaVMs (jvms , 32 , & vms ) >= 0 ) ? vms : 0 ;
96+ }
97+
8898/* in reality WIN64 implies WIN32 but to make sure ... */
8999#if defined(_WIN64 ) || defined(_WIN32 )
90100#include <io.h>
@@ -186,6 +196,7 @@ static int initJVM(const char *user_classpath, int opts, char **optv, int hooks,
186196 if (!eenv )
187197 error ("Cannot obtain JVM environment" );
188198
199+ rJava_JVM_state = JVM_STATE_CREATED ;
189200#if defined(_WIN64 ) || defined(_WIN32 )
190201 _setmode (0 , _O_TEXT );
191202#endif
@@ -217,6 +228,8 @@ static void *initJVMthread(void *classpath)
217228 thInitResult = initJVM ((char * )classpath , jvm_opts , jvm_optv , default_hooks , 0 );
218229 if (thInitResult ) return 0 ;
219230
231+ rJava_JVM_state = JVM_STATE_CREATED ;
232+
220233 init_rJava ();
221234
222235 lenv = eenv ; /* we make a local copy before unlocking just in case
@@ -357,7 +370,10 @@ static SEXP RinitJVM_real(SEXP par, int disableGuardPages)
357370 while (i < vms ) {
358371 if (jvms [i ]) {
359372 if (!(* jvms [i ])-> AttachCurrentThread (jvms [i ], (void * * )& eenv , NULL )) {
360- _dbg (rjprintf ("RinitJVM: Attached to existing JVM #%d.\n" , i + 1 ));
373+ /* attaching our own created JVM doesn't change it to attached */
374+ if (rJava_JVM_state != JVM_STATE_CREATED )
375+ rJava_JVM_state = JVM_STATE_ATTACHED ;
376+ _dbg (rjprintf ("RinitJVM: Attached to existing JVM #%d.\n" , i + 1 ));
361377 break ;
362378 }
363379 }
@@ -389,6 +405,8 @@ static SEXP RinitJVM_real(SEXP par, int disableGuardPages)
389405 _dbg (rjprintf ("RinitJVM(threads): attach\n" ));
390406 /* since JVM was initialized by another thread, we need to attach ourselves */
391407 (* jvm )-> AttachCurrentThread (jvm , (void * * )& eenv , NULL );
408+ if (rJava_JVM_state != JVM_STATE_CREATED )
409+ rJava_JVM_state = JVM_STATE_ATTACHED ;
392410 _dbg (rjprintf ("RinitJVM(threads): done.\n" ));
393411 r = thInitResult ;
394412#else
@@ -752,6 +770,7 @@ REP void doneJVM() {
752770 (* jvm )-> DestroyJavaVM (jvm );
753771 jvm = 0 ;
754772 eenv = 0 ;
773+ rJava_JVM_state = JVM_STATE_DESTROYED ;
755774}
756775
757776/**
0 commit comments