JNI_GetCreatedJavaVMs() returns 0 nVMs
843829Aug 9 2001 — edited Aug 13 2001Hello all
I am currently experiencing a very annoying problem.
I have a function CallJavaClient() that I need to call twice.
(See below for listing).
When I do the calls from within a console application, everything
works fine, but when I perform the calls from within a DLL (as required)
the second call of CallJavaClient() doesn't succeed.
The problem seems to stem from the call to JNI_GetCreatedJavaVMs().
This function always return nVMs == 0 when calling from the DLL.
So then the function JNI_CreateJavaVM() is called, which causes
the program to stop since a VM is running.
Can anyone suggest what might be going on here?
Thanks in advance
G
(JDK 1.2.2; JRE 1.3.1 / Hotspot; Windows NT/2000;)
static int CallJavaClient(
const char* tssServletURL,
const char* DTD_Spec,
const char* sessionID,
const char* requestID,
const char* userID,
const char* mechanismType,
const char* operationType,
const char* transactionData,
const char* signature,
const char* className,
const char* methodName,
const char* jvmOption_compilerMode,
const char* jvmOption_classPath,
const char* jvmOption_nativeLibPath,
const char* jvmOption_verboseMode,
char* tssString,
char* usrMessage)
{
int rc = SM_AUTHAPI_SUCCESS;
jint jvmCreate = 0;
JNIEnv* env = NULL;
JavaVM* jvm = NULL;
JavaVMInitArgs vm_args;
JavaVMOption options[4];
JavaVMAttachArgs attArgs;
jint res;
JavaVM* vmBuf[10];
jsize bufLen = 10;
jsize nVMs;
char jvmOptionParam_ComplierMode[128];
char jvmOptionParam_ClassPath[128];
char jvmOptionParam_NativeLibPath[128];
char jvmOptionParam_VerboseMode[128];
sprintf( jvmOptionParam_ComplierMode, "-Djava.compiler=%s", jvmOption_compilerMode );
sprintf( jvmOptionParam_ClassPath, "-Djava.class.path=%s", jvmOption_classPath );
sprintf( jvmOptionParam_NativeLibPath, "-Djava.library.path=%s", jvmOption_nativeLibPath );
sprintf( jvmOptionParam_VerboseMode, "-verbose:%s", jvmOption_verboseMode );
options[0].optionString = (char*) jvmOptionParam_ComplierMode;
options[1].optionString = (char*) jvmOptionParam_ClassPath;
options[2].optionString = (char*) jvmOptionParam_NativeLibPath;
options[3].optionString = (char*) jvmOptionParam_VerboseMode;
vm_args.version = JNI_VERSION_1_2;
vm_args.options = options;
vm_args.nOptions = 4;
vm_args.ignoreUnrecognized = TRUE;
attArgs.version = JNI_VERSION_1_2;
attArgs.name = NULL;
attArgs.group = NULL;
res = JNI_GetCreatedJavaVMs( vmBuf, bufLen, &nVMs );
printf( "JNI_GetCreatedJavaVMs() res = %d nVMs = %d\n", res, nVMs );
if (res < 0)
{
printf("No Java VM is created\n");
}
else if (nVMs == 1)
{
printf("A Java VM is already created.\n");
jvm = vmBuf[0];
}
else if (nVMs == 0)
{
// In JDK 1.2, there is no longer any need to call JNI_GetDefaultJavaVMInitArgs.
//
jvmCreate = JNI_CreateJavaVM( &jvm, (void**) &env, &vm_args );
if( jvmCreate < 0 )
{
sprintf( usrMessage, "Failed to create Java Virtual Machine. %d\n", jvmCreate );
rc = SM_AUTHAPI_FAILURE;
}
}
if( rc == SM_AUTHAPI_SUCCESS )
{
res = jvm->AttachCurrentThread( (void**) &env, &attArgs );
if (res < 0)
{
sprintf( usrMessage, "Can't attach current thread\n" );
rc = SM_AUTHAPI_FAILURE;
}
}
if( rc == SM_AUTHAPI_SUCCESS )
{
// Find class.method
//
jclass cls = env->FindClass( className );
// Catch Exception
//
if( cls != 0 )
{
jmethodID mid =
env->GetStaticMethodID( cls, methodName, "([Ljava/lang/String;)Ljava/lang/String;" );
if( mid != 0 )
{
jstring jstr = NULL;
// Attempt to allocate an empty string object for later use
//
if( ( jstr = env->NewStringUTF ("") ) != NULL )
{
int numberOfArguments = sizeof( SM_AUTHAPI_JVM_ARGUMENT_LIST ) / sizeof( SM_AUTHAPI_JVM_ARGUMENT_LIST[0] );
jobjectArray args = env->NewObjectArray( numberOfArguments, env->FindClass("java/lang/String"), jstr );
env->SetObjectArrayElement( args, SM_AUTHAPI_JVM_ARGUMENT_INDEX_URL, env->NewStringUTF( tssServletURL ) );
env->SetObjectArrayElement( args, SM_AUTHAPI_JVM_ARGUMENT_INDEX_DTD, env->NewStringUTF( DTD_Spec ) );
env->SetObjectArrayElement( args, SM_AUTHAPI_JVM_ARGUMENT_INDEX_SESSIONID, env->NewStringUTF( sessionID ) );
env->SetObjectArrayElement( args, SM_AUTHAPI_JVM_ARGUMENT_INDEX_REQUESTID, env->NewStringUTF( requestID ) );
env->SetObjectArrayElement( args, SM_AUTHAPI_JVM_ARGUMENT_INDEX_USERID, env->NewStringUTF( userID ) );
env->SetObjectArrayElement( args, SM_AUTHAPI_JVM_ARGUMENT_INDEX_MECHANISMTYPE, env->NewStringUTF( mechanismType ) );
env->SetObjectArrayElement( args, SM_AUTHAPI_JVM_ARGUMENT_INDEX_OPERATIONTYPE, env->NewStringUTF( operationType ) );
env->SetObjectArrayElement( args, SM_AUTHAPI_JVM_ARGUMENT_INDEX_TRANSACTIONDATA, env->NewStringUTF( transactionData ) );
env->SetObjectArrayElement( args, SM_AUTHAPI_JVM_ARGUMENT_INDEX_SIGNATURE, env->NewStringUTF( signature ) );
// Call the Java method
//
//jstr = (jstring) env -> CallStaticObjectMethod( cls, mid, "c:\\tss\\testdata\\verify.xml", "http://nsmse80:450/servlet/verifysig" );
jstr = (jstring) env->CallStaticObjectMethod( cls, mid, args );
if( jstr != 0 )
{
// Java String to C++ char array (warning: error checking omitted)
//
const char* cstr = env->GetStringUTFChars( jstr, 0 );
strcpy( tssString, cstr );
env->ReleaseStringUTFChars( jstr, cstr );
env->DeleteLocalRef( jstr );
ParseTSSString( tssString, usrMessage );
rc = SM_AUTHAPI_SUCCESS;
}
else
{
sprintf( usrMessage, "Error retieving value from TSS\n" );
rc = SM_AUTHAPI_FAILURE;
}
}
else //if( ( jstr = env->NewStringUTF ("") ) == NULL )
{
sprintf( usrMessage, "Memory allocation error (jstr)\n" );
rc = SM_AUTHAPI_FAILURE;
}
}
else //if( mid == 0 )
{
sprintf( usrMessage, "Error calling static method %s\n", methodName );
rc = SM_AUTHAPI_FAILURE;
}
}
else
{
sprintf( usrMessage, "Can't find class %s\n", className );
rc = SM_AUTHAPI_FAILURE;
}
res = jvm->DetachCurrentThread();
printf( "DetachCurrentThread() res = %d\n", res );
res = JNI_GetCreatedJavaVMs( vmBuf, bufLen, &nVMs );
printf( "res = %d nVMs = %d\n", res, nVMs );
printf( "Calling DestroyJavaVM() ...\n" );
res = jvm->DestroyJavaVM();
printf( "DestroyJavaVM() res = %d nVMs = %d\n", res, nVMs );
}
else
{
sprintf( usrMessage, "Failed to create Java Virtual Machine. %d\n", jvmCreate );
rc = SM_AUTHAPI_FAILURE;
}
return( rc );
}