Skip to Main Content

Java HotSpot Virtual Machine

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Memory leak in JNI Interface

843829Dec 28 2006 — edited Dec 29 2006
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 XPLMATL_

CJField::CJField(IField *pField)
{
try {
if(pField) {
CComBSTR name, 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 XPLMATL_ */

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()
{
char msg[512];
jmethodID mid = 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.getJNIEnv()->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]);

jstring jname = GJConnector.getJNIEnv()->NewString((jchar *) m_name.c_str(), m_name.length());
jstring jvalue = GJConnector.getJNIEnv()->NewString((jchar *) m_value.c_str(), m_value.length());

m_jobj = GJConnector.getJNIEnv()->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::wstring result;
jmethodID mid = NULL;
jstring jresult = NULL;

try {
mid = get_MethodID(m_jcls, m_cls, m_methods[1]);

jresult = (jstring) GJConnector.getJNIEnv()->CallObjectMethod(m_jobj, mid);
if(_GJConnector.get_JNIEnv()->ExceptionCheck() == JNI_TRUE) { throw std::exception(get_Exception().c_str()); }
if(jresult) {
result = (wchar_t *) GJConnector.getJNIEnv()->GetStringChars(jresult, JNI_FALSE);
GJConnector.getJNIEnv()->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::wstring result;
jmethodID mid = NULL;
jstring jresult = NULL;

try {
mid = get_MethodID(m_jcls, m_cls, m_methods[2]);

jresult = (jstring) GJConnector.getJNIEnv()->CallObjectMethod(m_jobj, mid);
if(_GJConnector.get_JNIEnv()->ExceptionCheck() == JNI_TRUE) { throw std::exception(get_Exception().c_str()); }
if(jresult) {
result = (wchar_t *) GJConnector.getJNIEnv()->GetStringChars(jresult, NULL);
GJConnector.getJNIEnv()->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;
jstring jname = NULL;

try {
mid = get_MethodID(m_jcls, m_cls, m_methods[3]);

jname = GJConnector.getJNIEnv()->NewString((jchar *) name.c_str(), name.length());
GJConnector.getJNIEnv()->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;
jstring jvalue = NULL;

try {
mid = get_MethodID(m_jcls, m_cls, m_methods[4]);

jvalue = GJConnector.getJNIEnv()->NewString((jchar *) value.c_str(), value.length());
GJConnector.getJNIEnv()->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)
{
bool result = false;
jmethodID mid = NULL;

try {
mid = get_MethodID(m_jcls, m_cls, m_methods[5]);
jboolean b = GJConnector.getJNIEnv()->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)
{
bool result = false;
jmethodID mid = NULL;

try {
if(field) {
mid = get_MethodID(m_jcls, m_cls, m_methods[5]);
jboolean b = GJConnector.getJNIEnv()->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 XPLMATL_

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 /* XPLMATL_ */

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()
{
char msg[512];
jmethodID mid = 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.getJNIEnv()->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.getJNIEnv()->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)
{
jmethodID mid = NULL;
jboolean jresult = NULL;

try {
mid = get_MethodID(m_jcls, m_cls, m_methods[1]);
jresult = GJConnector.getJNIEnv()->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)
{
jmethodID mid = NULL;
jboolean jresult = NULL;

try {
if(field) {
mid = get_MethodID(m_jcls, m_cls, m_methods[1]);
jresult = GJConnector.getJNIEnv()->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)
{
jmethodID mid = NULL;

try {
mid = get_MethodID(m_jcls, m_cls, m_methods[2]);
GJConnector.getJNIEnv()->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)
{
jmethodID mid = NULL;
CJField *result = NULL;

try {
mid = get_MethodID(m_jcls, m_cls, m_methods[3]);
jobject jobj = GJConnector.getJNIEnv()->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.getJNIEnv()->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;
jmethodID mid = NULL;
jstring jname = NULL;

try {
mid = get_MethodID(m_jcls, m_cls, m_methods[4]);
jname = GJConnector.getJNIEnv()->NewStringUTF(name.c_str());
jobject jobj = GJConnector.getJNIEnv()->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.getJNIEnv()->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()
{
long result = 0;
jmethodID mid = NULL;

try {
mid = get_MethodID(m_jcls, m_cls, m_methods[5]);
result = GJConnector.getJNIEnv()->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)
{
bool result = false;
jmethodID mid = NULL;

try {
mid = get_MethodID(m_jcls, m_cls, m_methods[6]);
jboolean b = GJConnector.getJNIEnv()->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)
{
bool result = false;
jmethodID mid = NULL;

try {
if(field) {
mid = get_MethodID(m_jcls, m_cls, m_methods[6]);
jboolean b = GJConnector.getJNIEnv()->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)
{
bool result = false;
jmethodID mid = NULL;

try {
mid = get_MethodID(m_jcls, m_cls, m_methods[7]);
jboolean b = GJConnector.getJNIEnv()->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)
{
bool result = false;
jmethodID mid = NULL;

try {
if(fields) {
mid = get_MethodID(m_jcls, m_cls, m_methods[7]);
jboolean b = GJConnector.getJNIEnv()->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.getJNIEnv()->NewLocalRef(jobj);
if(m_jcls) GJConnector.getJNIEnv()->DeleteLocalRef(m_jcls);
m_jcls = GJConnector.getJNIEnv()->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::wstring result;
jmethodID mid = NULL;
jstring jstr = NULL;

try {
if((m_jobj == NULL) || (m_jcls == NULL)) { return result; }

mid = get_MethodID(m_jcls, m_cls, m_methods[0]);
jstr = (jstring) GJConnector.getJNIEnv()->CallObjectMethod(m_jobj, mid);
if(_GJConnector.get_JNIEnv()->ExceptionCheck() == JNI_TRUE) { throw std::exception(get_Exception().c_str()); }
if(jstr) {
result = (wchar_t *) GJConnector.getJNIEnv()->GetStringChars(jstr, NULL);
GJConnector.getJNIEnv()->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.getJNIEnv()->ExceptionOccurred();
GJConnector.getJNIEnv()->ExceptionClear();
jclass exceptionClass = GJConnector.getJNIEnv()->GetObjectClass(jobj);
jclass swClass = GJConnector.getJNIEnv()->FindClass("java/io/StringWriter");
jclass pwClass = GJConnector.getJNIEnv()->FindClass("java/io/PrintWriter");
jclass sbClass = GJConnector.getJNIEnv()->FindClass("java/lang/StringBuffer");
jmethodID initswID = GJConnector.getJNIEnv()->GetMethodID(swClass, "<init>", "()V" );
jmethodID initpwID = GJConnector.getJNIEnv()->GetMethodID(pwClass, "<init>", "(Ljava/io/Writer;)V" );
jmethodID printStackTraceID = GJConnector.getJNIEnv()->GetMethodID(exceptionClass, "printStackTrace", "(Ljava/io/PrintWriter;)V" );
jmethodID getbufferID = GJConnector.getJNIEnv()->GetMethodID(swClass, "getBuffer", "()Ljava/lang/StringBuffer;");
jobject swObj = GJConnector.getJNIEnv()->NewObject(swClass, initswID);
jobject pwObj = GJConnector.getJNIEnv()->NewObject(pwClass, initpwID, swObj);
GJConnector.getJNIEnv()->CallVoidMethod(jobj, printStackTraceID, pwObj);
jobject sbObj = GJConnector.getJNIEnv()->CallObjectMethod(swObj, getbufferID);
jmethodID strsbID = GJConnector.getJNIEnv()->GetMethodID(sbClass, "toString", "()Ljava/lang/String;" );
jstring stackTrace = (jstring) GJConnector.getJNIEnv()->CallObjectMethod(sbObj, strsbID );
if(stackTrace) {
result = (char*) GJConnector.getJNIEnv()->GetStringUTFChars(stackTrace, NULL);
GJConnector.getJNIEnv()->DeleteLocalRef(stackTrace);
}

GJConnector.getJNIEnv()->DeleteLocalRef(exceptionClass);
GJConnector.getJNIEnv()->DeleteLocalRef(swClass);
GJConnector.getJNIEnv()->DeleteLocalRef(pwClass);
GJConnector.getJNIEnv()->DeleteLocalRef(sbClass);
GJConnector.getJNIEnv()->DeleteLocalRef(jobj);
GJConnector.getJNIEnv()->DeleteLocalRef(swObj);
GJConnector.getJNIEnv()->DeleteLocalRef(pwObj);
GJConnector.getJNIEnv()->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::string result;
char cls[] = "java/lang/Class";
char msg[512];
jmethodID mid = NULL;
jclass jcls = NULL;
jobject jobj = NULL;
jstring jstr = NULL;

try {
if((m_jobj == NULL) || (m_jcls == NULL)) { return result; }

jcls = GJConnector.getJNIEnv()->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.getJNIEnv()->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.getJNIEnv()->CallObjectMethod(jobj, mid);
if(_GJConnector.get_JNIEnv()->ExceptionCheck() == JNI_TRUE) { throw std::exception(get_Exception().c_str()); }
if(jstr) {
result = (char*) GJConnector.getJNIEnv()->GetStringUTFChars(jstr, NULL);
GJConnector.getJNIEnv()->DeleteLocalRef(jstr);
}
GJConnector.getJNIEnv()->DeleteLocalRef(jobj);
}
GJConnector.getJNIEnv()->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.getJNIEnv()->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;
}
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Jan 26 2007
Added on Dec 28 2006
4 comments
415 views