/* * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab * Copyright (C) INRIA - Allan CORNET * * This file must be used under the terms of the CeCILL. * This source file is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt * */ /*--------------------------------------------------------------------------*/ #include #include #include #include "dynamiclibrary.h" #include "JVM.h" #include "JVM_functions.h" #include "MALLOC.h" #include "getScilabJavaVM.h" #include "getScilabJNIEnv.h" #include "fromjava.h" #include "localization.h" #include "getJvmOptions.h" /*--------------------------------------------------------------------------*/ static JavaVM *jvm_SCILAB = NULL; /*--------------------------------------------------------------------------*/ static BOOL HadAlreadyJavaVm = FALSE; /*--------------------------------------------------------------------------*/ static JavaVMOption *jvm_options = NULL; static int nOptions = 0; /*--------------------------------------------------------------------------*/ static void freeJavaVMOption(void) { if (jvm_options) { int j = 0; for (j = 0; j < nOptions; j++) { if (jvm_options[j].optionString) { FREE(jvm_options[j].optionString); jvm_options[j].optionString = NULL; } } nOptions = 0; } } /*--------------------------------------------------------------------------*/ JavaVM *getScilabJavaVM(void) { if (!jvm_SCILAB && IsFromJava()) { /* If getScilabJavaVM is called from C called itself from JavaSci * (in nwni mode) the function returns a JVM */ JavaVM *vm = 0; JavaVM **vmBuf = MALLOC(sizeof(JavaVM *) * 1); jsize size = 0; if (!hasJvmSymbolsLoaded()) { /* We load symbols of the current jvm already used */ LoadFunctionsJVM(NULL); } SciJNI_GetCreatedJavaVMs(vmBuf, 1, &size); if (size) { vm = *vmBuf; } FREE(vmBuf); return vm; } return jvm_SCILAB; } /*--------------------------------------------------------------------------*/ JNIEnv *getScilabJNIEnv(void) { JNIEnv *JNIEnv_SCILAB = NULL; jint res = 0; if (jvm_SCILAB) { #ifdef JNI_VERSION_1_6 res = (*jvm_SCILAB)->GetEnv(jvm_SCILAB, (void **)&JNIEnv_SCILAB, JNI_VERSION_1_6); #elif JNI_VERSION_1_4 res = (*jvm_SCILAB)->GetEnv(jvm_SCILAB, (void **)&JNIEnv_SCILAB, JNI_VERSION_1_4); #endif if (res == JNI_ERR) { #ifdef _MSC_VER MessageBox(NULL, gettext("\nError: Cannot return Scilab Java environment (JNIEnv_SCILAB).\n"), gettext("Error"), MB_ICONEXCLAMATION | MB_OK); #else fprintf(stderr, _("\nError: Cannot return Scilab Java environment (JNIEnv_SCILAB).\n")); #endif return NULL; } if (res == JNI_EDETACHED) { (*jvm_SCILAB)->AttachCurrentThread(jvm_SCILAB, (void **)&JNIEnv_SCILAB, NULL); } } else { #ifdef _MSC_VER MessageBox(NULL, gettext ("\nError: Cannot return Scilab Java environment (jvm_SCILAB): check if the JVM has been loaded by Scilab before calling this function.\n"), gettext("Error"), MB_ICONEXCLAMATION | MB_OK); #else fprintf(stderr, _ ("\nError: Cannot return Scilab Java environment (jvm_SCILAB): check if the JVM has been loaded by Scilab before calling this function.\n")); #endif } return JNIEnv_SCILAB; } /*--------------------------------------------------------------------------*/ BOOL startJVM(char *SCI_PATH) { JNIEnv *env = NULL; JavaVM *ptr_jvm = NULL; jint res = 0; if (IsFromJava()) { ptr_jvm = FindCreatedJavaVM(SCI_PATH); if (ptr_jvm) /* a jvm already exists in scilab process */ { HadAlreadyJavaVm = TRUE; jvm_SCILAB = ptr_jvm; env = getScilabJNIEnv(); } else { fprintf(stderr, _("\nWeird error. Calling from Java but haven't been able to find the already existing JVM.\n")); FreeDynLibJVM(); return FALSE; } } else { if (!LoadDynLibJVM(SCI_PATH)) { fprintf(stderr, _("\nCould not load JVM dynamic library (libjava).\n")); fprintf(stderr, _("Error: %s\n"), GetLastDynLibError()); fprintf(stderr, _("If you are using a binary version of Scilab, please report a bug http://bugzilla.scilab.org/.\n")); fprintf(stderr, _("If you are using a self-built version of Scilab, update the script bin/scilab to provide the path to the JVM.\n")); fprintf(stderr, _("The problem might be related to SELinux. Try to deactivate it.\n")); fprintf(stderr, _("Please also check that you are not trying to run Scilab 64 bits on a 32 bits system (or vice versa).\n")); return FALSE; } else { /** * http://java.sun.com/javase/6/docs/technotes/guides/jni/spec/invocation.html#wp15956 */ #define JVM_OPTIONS_FILENAME_FORMAT "%s/etc/jvm_options.xml" char *jvm_options_filename = NULL; long status = 0; JavaVMInitArgs vm_args; jvm_options_filename = (char *)MALLOC(sizeof(char) * ((int)strlen(JVM_OPTIONS_FILENAME_FORMAT) + (int)strlen(SCI_PATH) + 1)); sprintf(jvm_options_filename, JVM_OPTIONS_FILENAME_FORMAT, SCI_PATH); jvm_options = getJvmOptions(SCI_PATH, jvm_options_filename, &nOptions); if ((jvm_options == NULL) || (nOptions == 0)) { #ifdef _MSC_VER { #define FORMAT_MSG "\nImpossible to read %s.\n" char *msg = (char *)MALLOC(sizeof(char) * ((int)strlen(_(FORMAT_MSG)) + (int)strlen(jvm_options_filename) + 1)); if (msg) { sprintf(msg, _(FORMAT_MSG), jvm_options_filename); MessageBox(NULL, msg, gettext("Error"), MB_ICONEXCLAMATION | MB_OK); FREE(msg); msg = NULL; } } #else fprintf(stderr, _("\nImpossible to read %s.\n"), jvm_options_filename); #endif if (jvm_options_filename) { FREE(jvm_options_filename); jvm_options_filename = NULL; } exit(1); } else { if (jvm_options_filename) { FREE(jvm_options_filename); jvm_options_filename = NULL; } HadAlreadyJavaVm = FALSE; memset(&vm_args, 0, sizeof(vm_args)); SciJNI_GetDefaultJavaVMInitArgs(&vm_args); #ifdef JNI_VERSION_1_6 vm_args.version = JNI_VERSION_1_6; #elif JNI_VERSION_1_4 vm_args.version = JNI_VERSION_1_4; #else #ifdef _MSC_VER MessageBox(NULL, gettext("\nIncorrect version JNI (needs at least JDK 1.4).\n"), gettext("Error"), MB_ICONEXCLAMATION | MB_OK); #else fprintf(stderr, gettext("\nIncorrect version JNI (needs at least JDK 1.4).\n")); #endif exit(1); #endif vm_args.options = jvm_options; vm_args.nOptions = nOptions; vm_args.ignoreUnrecognized = FALSE; status = SciJNI_CreateJavaVM(&jvm_SCILAB, (JNIEnv **) & env, &vm_args); if (status != JNI_OK) { fprintf(stderr, _("Error in the creation of the Java VM: %s\n"), getJniErrorFromStatusCode(status)); FreeDynLibJVM(); if (vm_args.options) { int j = 0; fprintf(stderr, _("Options:\n")); for (j = 0; j < vm_args.nOptions; j++) { fprintf(stderr, "%d: %s\n", j, vm_args.options[j]); } } return FALSE; } } } } res = (*jvm_SCILAB)->AttachCurrentThread(jvm_SCILAB, (void **)&env, (void *)NULL); if (res != 0) { #ifdef _MSC_VER MessageBox(NULL, gettext("\nJVM error in AttachCurrentThread: Could not attach to the current thread.\n"), gettext("Error"), MB_ICONEXCLAMATION | MB_OK); #else fprintf(stderr, gettext("\nJVM error in AttachCurrentThread: Could not attach to the current thread.\n")); #endif FreeDynLibJVM(); freeJavaVMOption(); return FALSE; } else { return TRUE; } } /*--------------------------------------------------------------------------*/ BOOL finishJVM(void) { BOOL bOK = FALSE; if (jvm_SCILAB) { // Detach the shared thread, to let the JVM finish itself (*jvm_SCILAB)->DetachCurrentThread(jvm_SCILAB); // force destroy the JVM (commented due to the javasci case) // (*jvm_SCILAB)->DestroyJavaVM(jvm_SCILAB); } if (FreeDynLibJVM()) { jvm_SCILAB = NULL; bOK = TRUE; } freeJavaVMOption(); return bOK; } /*--------------------------------------------------------------------------*/ BOOL isItTheDisabledLib(void) { return FALSE; } /*--------------------------------------------------------------------------*/