Can a C++ s-function that uses JNI to interface with a Java class be built into an executable with Simulink Coder?

10 views (last 30 days)
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;
}

Accepted Answer

Randal Guendel
Randal Guendel on 17 Jun 2015
I answered my own question: yes, Simulink Coder is able to handle the interface with Java. My problem was the call to DestroyJavaVM.

More Answers (0)

Categories

Find more on Simulink Coder in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!