Access violation calling CallStaticObjectMethod
843829May 2 2008 — edited May 6 2008Hi Everyone,
I have written a native COM app that is a C++ wrap class for my Java class to be call from VB or asp pages. It works fine, I can get native to java communication to work. My concern is that I have noticed that in the VC++ console debugger when I make a call to the env->CallStaticObjectMethod method the debug console log these lines,
First-chance exception at 0x0119e602 in GELibrariesAPIService.exe: 0xC0000005: Access violation reading location 0x00000004.
First-chance exception at 0x0119e602 in GELibrariesAPIService.exe: 0xC0000005: Access violation reading location 0x00000004.
First-chance exception at 0x0119e602 in GELibrariesAPIService.exe: 0xC0000005: Access violation reading location 0x00000004.
First-chance exception at 0x0119e602 in GELibrariesAPIService.exe: 0xC0000005: Access violation reading location 0x00000004.
First-chance exception at 0x0119e602 in GELibrariesAPIService.exe: 0xC0000005: Access violation reading location 0x00000004.
First-chance exception at 0x0119e602 in GELibrariesAPIService.exe: 0xC0000005: Access violation reading location 0x00000004.
First-chance exception at 0x0119e602 in GELibrariesAPIService.exe: 0xC0000005: Access violation reading location 0x00000004.
I'm not quite sure why a jni method throws this. I have made sure that I'm passing the proper types and values for the parameters of the method. This is the code that I'm calling.
BOOL JVM::callAPI(LPCTSTR xml, LPCTSTR userId, LPCTSTR appId, LPCTSTR appPassword, VARIANT *output)
{
//Log("Starting JVM::callAPI()");
USES_CONVERSION;
TCHAR TMP_LOGGING_STRING[MAX_LOG_STRING];
LPCTSTR FUNCNAME = A2T("JVM::callAPI");
BOOL status = FALSE;
//Before we attempt to perform any action in the JVM we have to attach the current thread to it.
status = this->AttachCurrentThread();
if( status == TRUE ) {
//Find The callAPI Method in the Class
jmethodID mid;
status = this->GetStaticMethodID(FUNCNAME,A2T("callAPI"),A2T("(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"),mid);
if( status == TRUE)
{
//wsprintf(TMP_LOGGING_STRING,A2T("About to call JVM::callAPI --> Input parameters:%s,%s,%s.\n"), xml, userId, appId);
//LogT(TMP_LOGGING_STRING);
// Create equivalent Java String. This java string don't have to be release because once the CallStaticObjectMethod and
// the JVM::callAPI method finish they will be out of scope and will be elected for the JVM garbarge collector.
NEWJSTRING(FUNCNAME, jstr1, xml, "xml")
NEWJSTRING(FUNCNAME, jstr2, userId, "userId")
NEWJSTRING(FUNCNAME, jstr3, appId, "appId")
NEWJSTRING(FUNCNAME, jstr4, appPassword, "appPassword")
{color:#0000ff} jstring xmlResponse = (jstring) this->env->CallStaticObjectMethod( cls, mid, jstr1,jstr2,jstr3,jstr4);{color}
status = this->CreateVariantResponseForASP(xmlResponse, FUNCNAME,output);
RELEASESTRING(jstr1)
RELEASESTRING(jstr2)
RELEASESTRING(jstr3)
RELEASESTRING(jstr4)
}
} else {
//Return without to attempt to detach the current thread. Because it could not be attached.
//Log("Leaving JVM::callAPI()");
return status;
}
//Before leaving this method we have to release the current thread from the JVM.
status = this->DetachCurrentThread();
//Log("Leaving JVM::callAPI()");
return status;
}
Macros being used,
#define NEWJSTRING(funcName,JStringName,CStringName,CStringDesc) \
jstring JStringName; \
\
wsprintf(TMP_LOGGING_STRING,A2T("%s --> About to call NewString for %s.\n"), funcName, A2T(CStringDesc)); \
LogT(TMP_LOGGING_STRING); \
JStringName = this->env->NewString((const jchar*)CStringName,SysStringLen((BSTR) CStringName)); \
\
if (JStringName == 0) \
{ \
wsprintf(TMP_LOGGING_STRING,A2T("%s --> Fail to get a NewString for %s. Out of memory.\n"), funcName, A2T(CStringDesc)); \
LogT(TMP_LOGGING_STRING); \
this->DetachCurrentThread(); \
return FALSE; \
} \
else \
{ \
wsprintf(TMP_LOGGING_STRING,A2T("%s --> Successfully created a NewString for %s.\n"), funcName, A2T(CStringDesc)); \
LogT(TMP_LOGGING_STRING); \
}
#define RELEASESTRING( str1 ) \
if( str1 != NULL ) \
{\
this->env->DeleteLocalRef(str1);\
}
The line on blue color is the line that is logging the Access violation. I wanted to make clear that the app is working I can get back the java results and send them back to the COM apps.
It is just I can't find what is wrong with it. I hope I can get some helpful light from some of you in the community.
Thanks :)