I am using JNI (and now JNA to see if the issue changes) to connect Java to a C code. This code has two methods that I am trying to use and they should be called from Java code many times, however, when I do the native calls, I got it:
- Call method one = I got a response
- Call method two = I got a response
- Call method one again = Attempt to reference unallocated memory
(Signal SIGSEGV) - Execution stops with this failure.
I tried to call the first and second methods alone (not calling them one after other) and the issue doesn't occur. It just happens when I call one after other, just like they should work. Looks like I am not freeing the memory as I should or JNA/JNI is doing it.
C code (JNI)
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "struct1.h"
#include "struct2.h"
#include "struct3.h"
#include "CALLExternMethod1s.h" //Interface External method
#include "CALLExternMethod2s.h" //Interface External method
#include "com_Method1Java.h" //Interface to Java Class
#include "com_Method2Java.h" //Interface to Java Class
void printStruct(void * structPar, int structSize) {
char buffer[structSize + 1];
memcpy(buffer, structPar, structSize);
buffer[structSize] = 0x00;
printf("{'%s'}\n", buffer);
}
JNIEXPORT jstring JNICALL Java_com_Method1Java_method1(JNIEnv *env, jobject obj, jstring input){
jboolean isCopy;
const char *request = (*env)->GetStringUTFChars(env, input, &isCopy);
struct1 struct1rec;
struct2 struct2rec;
char* response;
int reqLen = strlen(request);
reqLen = (reqLen <= sizeof(struct1)) ? reqLen : sizeof(struct1);
memcpy(&struct1rec, request, reqLen );
printf(" \n------ Struct1 Request ------\n ");
printStruct(&struct1rec, sizeof(struct1));
cob_init(0,NULL);
CALLExternMethod1(&struct1rec,&struct2rec); //Method overrides struct2rec with the response
response = malloc(sizeof(struct2) + 1);
memset(response, 0x20, sizeof(struct2) );
memcpy(response, &struct2rec, sizeof(struct2));
response[sizeof(struct2)] = '\0';
printf(" \n------ Struct2 Response ------\n ");
printStruct(response, sizeof(struct2));
(*env)->ReleaseStringUTFChars(env, input, request);
jstring result = (*env)->NewStringUTF(env, response);
free(response);
(*env)->PopLocalFrame(env,NULL);
printf("--- end of method1 JNI ---\n");
return result;
}
JNIEXPORT jstring JNICALL Java_com_Method2Java__struct3(JNIEnv *env, jobject obj, jstring input){
jboolean isCopy;
const char *request = (*env)->GetStringUTFChars(env, input, &isCopy);
struct3 struct3rec;
char* response;
int reqLen = strlen(request);
reqLen = (reqLen <= sizeof(struct3)) ? reqLen : sizeof(struct3);
memcpy(&struct3rec, request, reqLen );
printf("\n------ Struct3 Request ------\n");
printStruct(&struct3rec, sizeof(struct3));
cob_init(0,NULL);
CALLExternMethod2(&struct3rec); //Method overrides struct3Rec with the response
response = malloc(sizeof(struct3) + 1);
memset(response, 0x20, sizeof(struct3) );
memcpy(response, &struct3rec, sizeof(struct3));
response[sizeof(struct3)] = '\0';
printf("\n------ Struct3 Response ------\n");
printStruct(response, sizeof(struct3));
(*env)->ReleaseStringUTFChars(env, input, request);
jstring result = (*env)->NewStringUTF(env, response);
free(response);
printf("--- end of method2 JNI ---\n");
(*env)->PopLocalFrame(env,NULL);
return result;
}
C code (JNA)
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "struct1.h"
#include "struct2.h"
#include "struct3.h"
#include "CALLExternMethod1s.h" //Interface External method
#include "CALLExternMethod2s.h" //Interface External method
void printStruct(void * structPar, int structSize) {
char buffer[structSize + 1];
memcpy(buffer, structPar, structSize);
buffer[structSize] = 0x00;
printf("{'%s'}\n", buffer);
}
char* method1(char *request){
struct1 struct1rec;
struct2 struct2rec;
char* response;
int reqLen = strlen(request);
reqLen = (reqLen <= sizeof(struct1)) ? reqLen : sizeof(struct1);
memcpy(&struct1rec, request, reqLen);
printf("\n------ Struct1 Request -------- \n");
printStruct(&struct1rec, sizeof(struct1));
CALLExternMethod1(&struct1rec, &struct2rec); //Method overrides struct2rec with the response
printf("\n------ Struct2 Response -------- \n");
printStruct(&struct2rec, sizeof(struct2));
response = malloc(sizeof(struct2) + 1);
memset(response, 0x20, sizeof(struct2) );
memcpy(response, &struct2rec, sizeof(struct2));
response[sizeof(struct2)] = '\0';
char* result;
memset(result, 0x20, sizeof(struct2));
result = response;
free(response);
return result;
}
char* method2(char *request){
struct3 struct3Rec;
char* response;
memcpy(&struct3Rec,request, sizeof(struct3));
printf("\n------ Struct3 Request -------- \n");
printStruct(&struct3Rec, sizeof(struct3));
CALLExternMethod2(&struct3Rec); //Method overrides struct3Rec with the response
printf("\n------ Struct3 Response -------- \n");
printStruct(&struct3Rec,sizeof(struct3));
response = malloc(sizeof(struct3) + 1);
memset(response, 0x20, sizeof(struct3) );
memcpy(response, &struct3Rec, sizeof(struct3));
response[sizeof(struct3)] = '\0';
char* result;
memcpy(result, response, sizeof(struct3));
return result;
}
int main(int argc, char** args){
return 0;
}
Java Call
(...)
static {
System.loadLibrary("libstuff");
}
public static synchronized native String method1(String struct);
(...)
CALLExternMethod1 and CALLExternMethod2 are not the problem. The issue happens even when there is fake response and methods are not used.
Anybody with the same issue?