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;

}

[30009 byte] By [BillGehtsa] at [2007-11-26 13:40:13]
# 1
You must be joking.
bschauwejavaa at 2007-7-7 22:36:13 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 2
LOL!
caffeinea at 2007-7-7 22:36:13 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 3

> I have developed two simple Java and corresponding

> C++ classes.

Use code tags when you post your code.

You are missing a lot of error checking. JNI calls, every single one, will usually be followed by some sort of error checking. Any that access classes, methods, fields or allocate object must be followed by checks for java exceptions.

You will need to reduce your code to a smaller sample. Otherwise it is unlikely anyone will look at it.

You also need to specify how you know that a memory leak is occurring.

jschella at 2007-7-7 22:36:13 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 4
Thread closed!
BillGehtsa at 2007-7-7 22:36:13 > top of Java-index,Java HotSpot Virtual Machine,Specifications...