I'm trying to make use of some 3rd party Java classes within a Simulink model. I've created a C++ wrapper to the classes that uses JNI, and I've built an s-function of that wrapper. It works fine when I run the model within Simulink, and I'm able to use the Coder to build an executable. However, running the executable fails with the following message:
# A fatal error has been detected by the Java Runtime Environment:## SIGSEGV (0xb) at pc=0x000000000040e4d2, pid=20518, tid=140630443198240## JRE version: OpenJDK Runtime Environment (7.0_79-b14) (build 1.7.0_79-mockbuild_2015_05_14_07_23-b00)# Java VM: OpenJDK 64-Bit Server VM (24.79-b02 mixed mode linux-amd64 compressed oops)# Derivative: IcedTea 2.5.5# Distribution: CentOS release 6.6 (Final), package rhel-2.5.5.3.el6_6-x86_64 u79-b14# Problematic frame:# C [test_java_as_RSIM+0xe4d2]#
I wondered if anything about the Coder would preclude the Java interface, and if not, whether anyone has any suggestions on getting this to work.
My code is as follows:
#include <stdio.h>#include <jni.h>#include "java_convert.h"JNIEnv* get_or_create_vm(JavaVM **jvm, int* gc){ JNIEnv* env; JavaVMInitArgs args; JavaVMOption* options = new JavaVMOption[1]; args.version = JNI_VERSION_1_6; args.nOptions = 1; options[0].optionString = (char *)"-Djava.class.path=./myjavalibs/thirdparty.jar"; args.options = options; args.ignoreUnrecognized = false; int n; int status; // try to get and attach to existing VM first status = JNI_GetCreatedJavaVMs(jvm, 1, (jsize*) &n); if (status == JNI_OK && n == 1) { status = (*jvm)->AttachCurrentThread((void**)&env, &args); } // if not successful, create a new VM if (status != JNI_OK || n != 1) { status = JNI_CreateJavaVM(jvm, (void**)&env, &args); *gc = 1; } //status = JNI_CreateJavaVM(jvm, (void**)&env, &args); delete options; return env;}jdouble invoke_class(JNIEnv* env, jdouble cas, jdouble altitude){ jclass thirdparty_class; jmethodID convert_method; thirdparty_class = env->FindClass("common/utils/aClass"); jthrowable exc; exc = env->ExceptionOccurred(); if (exc) { env->ExceptionDescribe(); env->ExceptionClear(); } else { convert_method = env->GetStaticMethodID(thirdparty_class, "convertCasToTas", "(DD)D"); return env->CallStaticDoubleMethod(thirdparty_class, convert_method, cas, altitude); }}double call_java_class(double cas, double altitude) { JavaVM *jvm = NULL; JNIEnv *env = NULL; int gc = 0; env = get_or_create_vm(&jvm, &gc); if(env == NULL) return -1; double tas = invoke_class(env, cas, altitude); if (gc == 1) { jvm->DestroyJavaVM(); } return tas; }
Best Answer