Memory leak in JNI Interface
I have developed two simple Java and corresponding C++ classes.
Here is my example code which has memory leaks:
CJFieldCollection *fieldCollection;
fieldCollection = new CJFieldCollection();
for(int i=1; i<100000; i++) {
CJField *field = new CJField(L"hhhhhhhhhhhhhhh", L"wwwwwwwwwwwwww");
fieldCollection->add(field);
delete(field);
}
MessageBox(NULL, "1", "", MB_OK);
delete(fieldCollection);
MessageBox(NULL, "2", "", MB_OK);
It seems to me that the linked list in the CFieldCollection class is the reason for my memory leak in JNI implementation. I can ceate a loop with thousends of CField objects and releasing it without any problems. After adding a CField object from JNI to CField class in Java the object cannot correct released in JNI.
I have absolutely no ideas. I can send you the complete source code.
#############################################################################################################
package com.xplm.datatypes;
import java.io.*;
public class CField implements IField, Serializable
{
private String m_name = null;
private String m_value = null;
public CField(String name, String value)
{
m_name = name;
m_value = value;
}
public String get_Name() throws Exception
{
return m_name;
}
public void set_Name(String name) throws Exception
{
m_name = name;
}
public String get_Value() throws Exception
{
return m_value;
}
public void set_Value(String value) throws Exception
{
m_value = value;
}
}
package com.xplm.datatypes;
import java.io.*;
import java.util.*;
public class CFieldCollection implements IFieldCollection, Serializable
{
private LinkedList m_list = new LinkedList();
public CFieldCollection()
{
}
public boolean add(IField field) throws Exception
{
return (m_list.add(field));
}
public IField get_Item(int i) throws Exception
{
return ((IField) m_list.get(i));
}
public void remove(int index) throws Exception
{
m_list.remove(index);
}
public IField get_ItemByName(String name) throws Exception
{
Iterator iter = m_list.iterator();
while(iter.hasNext()) {
IField field = (IField) iter.next();
if(field.get_Name().equals(name)) { return field; }
}
return null;
}
public int size() throws Exception
{
return m_list.size();
}
public boolean isEqual(IFieldCollection fields) throws Exception
{
boolean result = false;
if(this == fields) { return true; }
if(fields != null) {
if(size() == fields.size()) {
Iterator iter = m_list.iterator();
while(iter.hasNext()) {
IField field = (IField) iter.next();
result = fields.isInCollection(field);
if(result == false) { return result; }
}
result = true;
}
}
return result;
}
public boolean isInCollection(IField field) throws Exception
{
boolean result = false;
if(field != null) {
Iterator iter = m_list.iterator();
while(iter.hasNext()) {
IField f = (IField) iter.next();
result = f.isEqual(field);
if(result == true) { return result; }
}
}
return result;
}
public void set_Field(IField field) throws Exception
{
if(field != null) {
IField f = get_ItemByName(field.get_Name());
if(f == null) {
add(field);
} else {
f.set_Value(field.get_Value());
}
}
}
}
The C++ code looks like this:
#include "stdafx.h"
#include "jfield.h"
using namespace xplm::jni;
#ifdef _XPLM_ATL_
CJField::CJField(IField *pField)
{
try {
if(pField) {
CComBSTRname, value;
EVAL_HR(pField->get_Name(&name), pField);
EVAL_HR(pField->get_StringValue(&value), pField);
m_name= name;
m_value= value;
init();
} else { throw std::exception("null pointer exception"); }
}
catch(std::exception e) { throw std::exception(e); }
catch(_com_error e){ throw e.Description(); }
catch(...){ throw std::exception("unknown error in method CJField::CJField(IField *pField)"); }
}
void CJField::toIField(IField **ppField)
{
*ppField = NULL;
try {
CComPtr<IField> pField;
EVAL_HR(pField.CoCreateInstance(__uuidof(CField)));
EVAL_HR(pField->put_Name(CComBSTR(this->get_Name().c_str())), pField);
EVAL_HR(pField->put_Value(CComVariant(this->get_Value().c_str())), pField);
EVAL_HR(pField.CopyTo(ppField), pField);
}
catch(std::exception e) { throw std::exception(e); }
catch(_com_error e){ throw e.Description(); }
catch(...){ throw std::exception("unknown error in method void CJField::toIField(IField **ppField)"); }
}
#endif /* #ifdef _XPLM_ATL_ */
CJField::CJField(const std::wstring& name, const std::wstring& value)
{
try {
m_name= name;
m_value= value;
init();
}
catch(std::exception e) { throw std::exception(e); }
catch(...){ throw std::exception("unknown error in method CJField::CJField(const char *name, const char *value)"); }
}
CJField::CJField(jobject jobj)
{
try {
set_JObject(jobj);
init();
}
catch(std::exception e) { throw std::exception(e); }
catch(...){ throw std::exception("unknown error in method CJField::CJField(jobject jobj)"); }
}
CJField::~CJField(void)
{
}
void CJField::init()
{
charmsg[512];
jmethodIDmid= NULL;
try {
_GJConnector.createJavaVirtualMachine();
m_cls= "com/xplm/datatypes/CField";
m_methods.push_back(CJMethod("<init>", "(Ljava/lang/String;Ljava/lang/String;)V"));
m_methods.push_back(CJMethod("get_Name", "()Ljava/lang/String;"));
m_methods.push_back(CJMethod("get_Value", "()Ljava/lang/String;"));
m_methods.push_back(CJMethod("set_Name" , "(Ljava/lang/String;)V"));
m_methods.push_back(CJMethod("set_Value", "(Ljava/lang/String;)V"));
m_methods.push_back(CJMethod("isEqual", "(Lcom/xplm/datatypes/IField;)Z"));
if(m_jobj == NULL) {
m_jcls = _GJConnector.get_JNIEnv()->FindClass(m_cls.c_str());
if(m_jcls == NULL) {
sprintf(msg, "error finding class %s.", m_cls.c_str());
throw std::exception(msg);
}
mid = get_MethodID(m_jcls, m_cls, m_methods[0]);
jstringjname= _GJConnector.get_JNIEnv()->NewString((jchar *) m_name.c_str(), m_name.length());
jstringjvalue= _GJConnector.get_JNIEnv()->NewString((jchar *) m_value.c_str(), m_value.length());
m_jobj = _GJConnector.get_JNIEnv()->NewObject(m_jcls, mid, jname, jvalue);
if(m_jobj == NULL) {
sprintf(msg, "Error creating new instance of %s", m_cls);
throw std::exception(msg);
}
if(jname){ _GJConnector.get_JNIEnv()->DeleteLocalRef(jname); }
if(jvalue){ _GJConnector.get_JNIEnv()->DeleteLocalRef(jvalue); }
}
}
catch(std::exception e) { throw std::exception(e); }
catch(...){ throw std::exception("unknown error in method void CJField::init()"); }
}
std::wstring CJField::get_Name()
{
std::wstringresult;
jmethodIDmid= NULL;
jstringjresult = NULL;
try {
mid = get_MethodID(m_jcls, m_cls, m_methods[1]);
jresult = (jstring) _GJConnector.get_JNIEnv()->CallObjectMethod(m_jobj, mid);
if(_GJConnector.get_JNIEnv()->ExceptionCheck() == JNI_TRUE) { throw std::exception(get_Exception().c_str()); }
if(jresult) {
result = (wchar_t *) _GJConnector.get_JNIEnv()->GetStringChars(jresult, JNI_FALSE);
_GJConnector.get_JNIEnv()->DeleteLocalRef(jresult);
}
}
catch(std::exception e) { throw std::exception(e); }
catch(...){ throw std::exception("unknown error in method std::wstring CJField::get_Name()"); }
return result;
}
std::wstring CJField::get_Value()
{
std::wstringresult;
jmethodIDmid= NULL;
jstringjresult = NULL;
try {
mid = get_MethodID(m_jcls, m_cls, m_methods[2]);
jresult = (jstring) _GJConnector.get_JNIEnv()->CallObjectMethod(m_jobj, mid);
if(_GJConnector.get_JNIEnv()->ExceptionCheck() == JNI_TRUE) { throw std::exception(get_Exception().c_str()); }
if(jresult) {
result = (wchar_t *) _GJConnector.get_JNIEnv()->GetStringChars(jresult, NULL);
_GJConnector.get_JNIEnv()->DeleteLocalRef(jresult);
}
}
catch(std::exception e) { throw std::exception(e); }
catch(...){ throw std::exception("unknown error in method std::wstring CJField::get_Value()"); }
return result;
}
void CJField::set_Name(const std::wstring& name)
{
jmethodID mid= NULL;
jstringjname = NULL;
try {
mid = get_MethodID(m_jcls, m_cls, m_methods[3]);
jname = _GJConnector.get_JNIEnv()->NewString((jchar *) name.c_str(), name.length());
_GJConnector.get_JNIEnv()->CallVoidMethod(m_jobj, mid, jname);
if(_GJConnector.get_JNIEnv()->ExceptionCheck() == JNI_TRUE) { throw std::exception(get_Exception().c_str()); }
if(jname) { _GJConnector.get_JNIEnv()->DeleteLocalRef(jname); }
}
catch(std::exception e) { throw std::exception(e); }
catch(...){ throw std::exception("unknown error in method std::wstring CJField::get_Value()"); }
}
void CJField::set_Value(const std::wstring& value)
{
jmethodID mid= NULL;
jstringjvalue = NULL;
try {
mid = get_MethodID(m_jcls, m_cls, m_methods[4]);
jvalue = _GJConnector.get_JNIEnv()->NewString((jchar *) value.c_str(), value.length());
_GJConnector.get_JNIEnv()->CallVoidMethod(m_jobj, mid, jvalue);
if(_GJConnector.get_JNIEnv()->ExceptionCheck() == JNI_TRUE) { throw std::exception(get_Exception().c_str()); }
if(jvalue) { _GJConnector.get_JNIEnv()->DeleteLocalRef(jvalue); }
}
catch(std::exception e) { throw std::exception(e); }
catch(...){ throw std::exception("unknown error in method std::wstring CJField::get_Value()"); }
}
bool CJField::isEqual(CJField& field)
{
boolresult = false;
jmethodIDmid= NULL;
try {
mid = get_MethodID(m_jcls, m_cls, m_methods[5]);
jboolean b = _GJConnector.get_JNIEnv()->CallBooleanMethod(m_jobj, mid, field.get_JObject());
if(_GJConnector.get_JNIEnv()->ExceptionCheck() == JNI_TRUE) { throw std::exception(get_Exception().c_str()); }
if(b == JNI_TRUE) { result = true; }
}
catch(std::exception e) { throw std::exception(e); }
catch(...){ throw std::exception("unknown error in method bool CJField::isEqual(const CJField& field)"); }
return result;
}
bool CJField::isEqual(CJField* field)
{
boolresult = false;
jmethodIDmid= NULL;
try {
if(field) {
mid = get_MethodID(m_jcls, m_cls, m_methods[5]);
jboolean b = _GJConnector.get_JNIEnv()->CallBooleanMethod(m_jobj, mid, field->get_JObject());
if(_GJConnector.get_JNIEnv()->ExceptionCheck() == JNI_TRUE) { throw std::exception(get_Exception().c_str()); }
if(b == JNI_TRUE) { result = true; }
}
}
catch(std::exception e) { throw std::exception(e); }
catch(...){ throw std::exception("unknown error in method bool CJField::isEqual(const CJField* field)"); }
return result;
}
#include "stdafx.h"
#include "jfieldcollection.h"
using namespace xplm::jni;
#ifdef _XPLM_ATL_
CJFieldCollection::CJFieldCollection(IFieldCollection *pFieldCollection)
{
try {
if(pFieldCollection) {
long size;
init();
EVAL_HR(pFieldCollection->get_Count(&size), pFieldCollection);
for(long i=1; i<=size; i++) {
CComPtr<IField> pField;
EVAL_HR(pFieldCollection->get_Item(i, &pField), pFieldCollection);
CJField field(pField);
this->add(field);
}
} else { throw std::exception("null pointer exception"); }
}
catch(std::exception e) { throw std::exception(e); }
catch(_com_error e){ throw e.Description(); }
catch(...){ throw std::exception("unknown error in method CJFieldCollection::CJFieldCollection(IFieldCollection *pFieldCollection)"); }
}
void CJFieldCollection::toIFieldCollection(IFieldCollection **ppFieldCollection)
{
*ppFieldCollection = NULL;
try {
CComPtr<IFieldCollection> pFieldCollection;
EVAL_HR(pFieldCollection.CoCreateInstance(__uuidof(CFieldCollection)));
for(int i=0; i<this->size(); i++) {
CComPtr<IField> pField;
CJField *field = this->get_Item(i);
field->toIField(&pField);
EVAL_HR(pFieldCollection->Add(pField), pFieldCollection);
delete(field);
}
EVAL_HR(pFieldCollection.CopyTo(ppFieldCollection), pFieldCollection);
}
catch(std::exception e) { throw std::exception(e); }
catch(_com_error e){ throw e.Description(); }
catch(...){ throw std::exception("unknown error in method void CJFieldCollection::toIFieldCollection(IFieldCollection **ppFieldCollection)"); }
}
#endif /* _XPLM_ATL_ */
CJFieldCollection::CJFieldCollection(void)
{
try {
init();
}
catch(std::exception e) { throw std::exception(e); }
catch(...){ throw std::exception("unknown error in method CJFieldCollection::CJFieldCollection(void)"); }
}
CJFieldCollection::CJFieldCollection(jobject jobj)
{
try {
set_JObject(jobj);
init();
}
catch(std::exception e) { throw std::exception(e); }
catch(...){ throw std::exception("unknown error in method CJFieldCollection::CJFieldCollection(jobject jobj)"); }
}
CJFieldCollection::~CJFieldCollection(void)
{
}
void CJFieldCollection::init()
{
charmsg[512];
jmethodIDmid= NULL;
try {
_GJConnector.createJavaVirtualMachine();
m_cls = "com/xplm/datatypes/CFieldCollection";
m_methods.push_back(CJMethod("<init>", "()V"));
m_methods.push_back(CJMethod("add", "(Lcom/xplm/datatypes/IField;)Z"));
m_methods.push_back(CJMethod("remove", "(I)V"));
m_methods.push_back(CJMethod("get_Item", "(I)Lcom/xplm/datatypes/IField;"));
m_methods.push_back(CJMethod("get_ItemByName", "(Ljava/lang/String;)Lcom/xplm/datatypes/IField;"));
m_methods.push_back(CJMethod("size", "()I"));
m_methods.push_back(CJMethod("isInCollection", "(Lcom/xplm/datatypes/IField;)Z"));
m_methods.push_back(CJMethod("isEqual", "(Lcom/xplm/datatypes/IFieldCollection;)Z"));
if(m_jobj == NULL) {
m_jcls = _GJConnector.get_JNIEnv()->FindClass(m_cls.c_str());
if(m_jcls == NULL) {
sprintf(msg, "error finding class %s.", m_cls.c_str());
throw std::exception(msg);
}
mid = get_MethodID(m_jcls, m_cls, m_methods[0]);
m_jobj = _GJConnector.get_JNIEnv()->NewObject(m_jcls, mid);
if(m_jobj == NULL) {
sprintf(msg, "error creating new instance %s", m_cls.c_str());
throw std::exception(msg);
}
}
}
catch(std::exception e) { throw std::exception(e); }
catch(...){ throw std::exception("unknown error in method void CJFieldCollection::init()"); }
}
void CJFieldCollection::add(CJField& field)
{
jmethodIDmid= NULL;
jbooleanjresult = NULL;
try {
mid = get_MethodID(m_jcls, m_cls, m_methods[1]);
jresult = _GJConnector.get_JNIEnv()->CallBooleanMethod(m_jobj, mid, field.get_JObject());
if(_GJConnector.get_JNIEnv()->ExceptionCheck() == JNI_TRUE) { throw std::exception(get_Exception().c_str()); }
}
catch(std::exception e) { throw std::exception(e); }
catch(...){ throw std::exception("unknown error in method void CJFieldCollection::add(CJField& field)"); }
}
void CJFieldCollection::add(CJField* field)
{
jmethodIDmid= NULL;
jbooleanjresult = NULL;
try {
if(field) {
mid = get_MethodID(m_jcls, m_cls, m_methods[1]);
jresult = _GJConnector.get_JNIEnv()->CallBooleanMethod(m_jobj, mid, field->get_JObject());
if(_GJConnector.get_JNIEnv()->ExceptionCheck() == JNI_TRUE) { throw std::exception(get_Exception().c_str()); }
}
}
catch(std::exception e) { throw std::exception(e); }
catch(...){ throw std::exception("unknown error in method void CJFieldCollection::add(CJField* field)"); }
}
void CJFieldCollection::remove(int index)
{
jmethodIDmid= NULL;
try {
mid = get_MethodID(m_jcls, m_cls, m_methods[2]);
_GJConnector.get_JNIEnv()->CallVoidMethod(m_jobj, mid, index);
if(_GJConnector.get_JNIEnv()->ExceptionCheck() == JNI_TRUE) { throw std::exception(get_Exception().c_str()); }
}
catch(std::exception e) { throw std::exception(e); }
catch(...){ throw std::exception("unknown error in method void CJFieldCollection::remove(int index)"); }
}
CJField* CJFieldCollection::get_Item(int index)
{
jmethodIDmid= NULL;
CJField*result = NULL;
try {
mid = get_MethodID(m_jcls, m_cls, m_methods[3]);
jobject jobj = _GJConnector.get_JNIEnv()->CallObjectMethod(m_jobj, mid, index);
if(_GJConnector.get_JNIEnv()->ExceptionCheck() == JNI_TRUE) { throw std::exception(get_Exception().c_str()); }
if(jobj) {
result = new CJField(jobj);
_GJConnector.get_JNIEnv()->DeleteLocalRef(jobj);
}
}
catch(std::exception e) { throw std::exception(e); }
catch(...){ throw std::exception("unknown error in method CJField* CJFieldCollection::get_Item(int index)"); }
return result;
}
CJField *CJFieldCollection::get_ItemByName(const std::string& name)
{
CJField*result = NULL;
jmethodIDmid= NULL;
jstringjname= NULL;
try {
mid = get_MethodID(m_jcls, m_cls, m_methods[4]);
jname = _GJConnector.get_JNIEnv()->NewStringUTF(name.c_str());
jobject jobj = _GJConnector.get_JNIEnv()->CallObjectMethod(m_jobj, mid, jname);
if(_GJConnector.get_JNIEnv()->ExceptionCheck() == JNI_TRUE) { throw std::exception(get_Exception().c_str()); }
if(jobj) {
result = new CJField(jobj);
_GJConnector.get_JNIEnv()->DeleteLocalRef(jobj);
}
if(jname){ _GJConnector.get_JNIEnv()->DeleteLocalRef(jname); }
}
catch(std::exception e) { throw std::exception(e); }
catch(...){ throw std::exception("unknown error in method CJField *CJFieldCollection::get_ItemByName(const std::string& name)"); }
return result;
}
long CJFieldCollection::size()
{
longresult= 0;
jmethodIDmid= NULL;
try {
mid = get_MethodID(m_jcls, m_cls, m_methods[5]);
result = _GJConnector.get_JNIEnv()->CallIntMethod(m_jobj, mid);
if(_GJConnector.get_JNIEnv()->ExceptionCheck() == JNI_TRUE) { throw std::exception(get_Exception().c_str()); }
}
catch(std::exception e) { throw std::exception(e); }
catch(...){ throw std::exception("unknown error in method long CJFieldCollection::size()"); }
return result;
}
bool CJFieldCollection::isInCollection(CJField& field)
{
boolresult= false;
jmethodIDmid= NULL;
try {
mid = get_MethodID(m_jcls, m_cls, m_methods[6]);
jboolean b = _GJConnector.get_JNIEnv()->CallBooleanMethod(m_jobj, mid, field.get_JObject());
if(_GJConnector.get_JNIEnv()->ExceptionCheck() == JNI_TRUE) { throw std::exception(get_Exception().c_str()); }
if(b == JNI_TRUE) { result = true; }
}
catch(std::exception e) { throw std::exception(e); }
catch(...){ throw std::exception("unknown error in method bool CJFieldCollection::isInCollection(CJField& field)"); }
return result;
}
bool CJFieldCollection::isInCollection(CJField* field)
{
boolresult= false;
jmethodIDmid= NULL;
try {
if(field) {
mid = get_MethodID(m_jcls, m_cls, m_methods[6]);
jboolean b = _GJConnector.get_JNIEnv()->CallBooleanMethod(m_jobj, mid, field->get_JObject());
if(_GJConnector.get_JNIEnv()->ExceptionCheck() == JNI_TRUE) { throw std::exception(get_Exception().c_str()); }
if(b == JNI_TRUE) { result = true; }
}
}
catch(std::exception e) { throw std::exception(e); }
catch(...){ throw std::exception("unknown error in method bool CJFieldCollection::isInCollection(CJField* field)"); }
return result;
}
bool CJFieldCollection::isEqual(CJFieldCollection& fields)
{
boolresult = false;
jmethodIDmid= NULL;
try {
mid = get_MethodID(m_jcls, m_cls, m_methods[7]);
jboolean b = _GJConnector.get_JNIEnv()->CallBooleanMethod(m_jobj, mid, fields.get_JObject());
if(_GJConnector.get_JNIEnv()->ExceptionCheck() == JNI_TRUE) { throw std::exception(get_Exception().c_str()); }
if(b == JNI_TRUE) { result = true; }
}
catch(std::exception e) { throw std::exception(e); }
catch(...){ throw std::exception("unknown error in method bool CJFieldCollection::isEqual(CJFieldCollection& fields)"); }
return result;
}
bool CJFieldCollection::isEqual(CJFieldCollection* fields)
{
boolresult = false;
jmethodIDmid= NULL;
try {
if(fields) {
mid = get_MethodID(m_jcls, m_cls, m_methods[7]);
jboolean b = _GJConnector.get_JNIEnv()->CallBooleanMethod(m_jobj, mid, fields->get_JObject());
if(_GJConnector.get_JNIEnv()->ExceptionCheck() == JNI_TRUE) { throw std::exception(get_Exception().c_str()); }
if(b == JNI_TRUE) { result = true; }
}
}
catch(std::exception e) { throw std::exception(e); }
catch(...){ throw std::exception("unknown error in method bool CJFieldCollection::isEqual(CJFieldCollection* fields)"); }
return result;
}
#include "stdafx.h"
#include "jbaseobject.h"
#include <stdlib.h>
#include <string.h>
using namespace xplm::jni;
CJBaseObject::CJBaseObject(void)
{
try {
m_jcls= NULL;
m_jobj= NULL;
m_methods.push_back(CJMethod("toString", "()Ljava/lang/String;"));
m_methods.push_back(CJMethod("getClass", "()Ljava/lang/Class;"));
m_methods.push_back(CJMethod("getName", "()Ljava/lang/String;"));
}
catch(std::exception e) {
throw std::exception(e);
}
catch(...) {
throw std::exception("unknown error in method CJBaseObject::CJBaseObject(void)");
}
}
CJBaseObject::~CJBaseObject(void)
{
if(m_jobj){ _GJConnector.get_JNIEnv()->DeleteLocalRef(m_jobj); m_jobj = NULL; }
if(m_jcls){ _GJConnector.get_JNIEnv()->DeleteLocalRef(m_jcls); m_jcls = NULL; }
}
jobject CJBaseObject::get_JObject()
{
return m_jobj;
}
void CJBaseObject::set_JObject(jobject jobj)
{
try {
if(jobj != m_jobj) {
if(jobj) {
if(m_jobj) { _GJConnector.get_JNIEnv()->DeleteLocalRef(m_jobj); }
m_jobj = _GJConnector.get_JNIEnv()->NewLocalRef(jobj);
if(m_jcls)_GJConnector.get_JNIEnv()->DeleteLocalRef(m_jcls);
m_jcls = _GJConnector.get_JNIEnv()->GetObjectClass(m_jobj);
}
}
}
catch(std::exception e) {
throw std::exception(e);
}
catch(...) {
throw std::exception("unknown error in method void CJBaseObject::set_JObject(jobject jobj)");
}
}
std::wstring CJBaseObject::toString()
{
std::wstringresult;
jmethodIDmid= NULL;
jstringjstr = NULL;
try {
if((m_jobj == NULL) || (m_jcls == NULL)) { return result; }
mid = get_MethodID(m_jcls, m_cls, m_methods[0]);
jstr = (jstring) _GJConnector.get_JNIEnv()->CallObjectMethod(m_jobj, mid);
if(_GJConnector.get_JNIEnv()->ExceptionCheck() == JNI_TRUE) { throw std::exception(get_Exception().c_str()); }
if(jstr) {
result = (wchar_t *) _GJConnector.get_JNIEnv()->GetStringChars(jstr, NULL);
_GJConnector.get_JNIEnv()->DeleteLocalRef(jstr);
}
}
catch(std::exception e) {
throw std::exception(e);
}
catch(...) {
throw std::exception("unknown error in method std::wstring CJBaseObject::toString()");
}
return result;
}
std::string CJBaseObject::get_Exception()
{
std::string result;
try {
if((m_jobj == NULL) || (m_jcls == NULL)) { return result; }
if(_GJConnector.get_JNIEnv()->ExceptionCheck() == JNI_TRUE) {
jthrowable jobj = _GJConnector.get_JNIEnv()->ExceptionOccurred();
_GJConnector.get_JNIEnv()->ExceptionClear();
jclass exceptionClass= _GJConnector.get_JNIEnv()->GetObjectClass(jobj);
jclass swClass= _GJConnector.get_JNIEnv()->FindClass("java/io/StringWriter");
jclass pwClass= _GJConnector.get_JNIEnv()->FindClass("java/io/PrintWriter");
jclass sbClass= _GJConnector.get_JNIEnv()->FindClass("java/lang/StringBuffer");
jmethodID initswID= _GJConnector.get_JNIEnv()->GetMethodID(swClass, "<init>", "()V" );
jmethodID initpwID= _GJConnector.get_JNIEnv()->GetMethodID(pwClass, "<init>", "(Ljava/io/Writer;)V" );
jmethodID printStackTraceID = _GJConnector.get_JNIEnv()->GetMethodID(exceptionClass, "printStackTrace", "(Ljava/io/PrintWriter;)V" );
jmethodID getbufferID= _GJConnector.get_JNIEnv()->GetMethodID(swClass, "getBuffer", "()Ljava/lang/StringBuffer;");
jobject swObj= _GJConnector.get_JNIEnv()->NewObject(swClass, initswID);
jobject pwObj= _GJConnector.get_JNIEnv()->NewObject(pwClass, initpwID, swObj);
_GJConnector.get_JNIEnv()->CallVoidMethod(jobj, printStackTraceID, pwObj);
jobject sbObj= _GJConnector.get_JNIEnv()->CallObjectMethod(swObj, getbufferID);
jmethodID strsbID= _GJConnector.get_JNIEnv()->GetMethodID(sbClass, "toString", "()Ljava/lang/String;" );
jstring stackTrace= (jstring) _GJConnector.get_JNIEnv()->CallObjectMethod(sbObj, strsbID );
if(stackTrace) {
result = (char*) _GJConnector.get_JNIEnv()->GetStringUTFChars(stackTrace, NULL);
_GJConnector.get_JNIEnv()->DeleteLocalRef(stackTrace);
}
_GJConnector.get_JNIEnv()->DeleteLocalRef(exceptionClass);
_GJConnector.get_JNIEnv()->DeleteLocalRef(swClass);
_GJConnector.get_JNIEnv()->DeleteLocalRef(pwClass);
_GJConnector.get_JNIEnv()->DeleteLocalRef(sbClass);
_GJConnector.get_JNIEnv()->DeleteLocalRef(jobj);
_GJConnector.get_JNIEnv()->DeleteLocalRef(swObj);
_GJConnector.get_JNIEnv()->DeleteLocalRef(pwObj);
_GJConnector.get_JNIEnv()->DeleteLocalRef(sbObj);
}
}
catch(std::exception e) {
throw std::exception(e);
}
catch(...) {
throw std::exception("unknown error in method std::string CJBaseObject::get_Exception()");
}
return result;
}
std::string CJBaseObject::get_Class()
{
std::stringresult;
charcls[] = "java/lang/Class";
charmsg[512];
jmethodIDmid= NULL;
jclassjcls= NULL;
jobjectjobj= NULL;
jstringjstr= NULL;
try {
if((m_jobj == NULL) || (m_jcls == NULL)) { return result; }
jcls = _GJConnector.get_JNIEnv()->FindClass(cls);
if(jcls == NULL) {
sprintf(msg, "error finding %s.", cls);
throw std::exception(msg);
}
mid = get_MethodID(m_jcls, m_cls, m_methods[1]);
jobj = _GJConnector.get_JNIEnv()->CallObjectMethod(m_jobj, mid);
if(_GJConnector.get_JNIEnv()->ExceptionCheck() == JNI_TRUE) { throw std::exception(get_Exception().c_str()); }
if(jobj) {
mid = get_MethodID(jcls, m_cls, m_methods[2]);
jstr = (jstring) _GJConnector.get_JNIEnv()->CallObjectMethod(jobj, mid);
if(_GJConnector.get_JNIEnv()->ExceptionCheck() == JNI_TRUE) { throw std::exception(get_Exception().c_str()); }
if(jstr) {
result = (char*) _GJConnector.get_JNIEnv()->GetStringUTFChars(jstr, NULL);
_GJConnector.get_JNIEnv()->DeleteLocalRef(jstr);
}
_GJConnector.get_JNIEnv()->DeleteLocalRef(jobj);
}
_GJConnector.get_JNIEnv()->DeleteLocalRef(jcls);
}
catch(std::exception e) {
throw std::exception(e);
}
catch(...) {
throw std::exception("unknown error in method std::string CJBaseObject::get_Class()");
}
return result;
}
jmethodID CJBaseObject::get_MethodID(jclass& jcls, std::string& cls, CJMethod& method)
{
jmethodID mid = NULL;
try {
mid = _GJConnector.get_JNIEnv()->GetMethodID(jcls, method.get_Method().c_str(), method.get_Convention().c_str());
if(mid == NULL) {
char msg[1024];
sprintf(msg, "error finding %s(%s) in %s.", method.get_Method().c_str(), method.get_Convention().c_str(), cls.c_str());
throw std::exception(msg);
}
}
catch(std::exception e) {
throw std::exception(e);
}
catch(...) {
throw std::exception("unknown error in method jmethodID CJBaseObject::get_MethodID(CJMethod& method)");
}
return mid;
}

