AttachCurrentThread not working w/ Windows services
I have a Windows service that calls a C++ DLL which invokes a Java class through JNI. With this configuration (running as a service), AttachCurrentThread crashes. But, if I run the app as a standalone client, everything is well.
Is there anything about services that makes attaching the current thread not work?
So, my C++ DLL (which is called by the service) makes a call to initialize JVM. Then the call is made to convert( ) where AttachCurrentThread( ) seems to fail. The reason why I know it's AttachCurrentThread that is failing is because I put print statements all around it and it never prints anything after the call.
Here is caller's pseudocode:
For iNum = 0 to x
'Successful initialization will return 0
If Init_JVM() = 0 then
Convert()
End If
Next
So, the first time it initializes the JVM, it's ok because it creates a new instance. The second time, it uses GetCreatedJavaVMs to get the instance loaded. When it attaches the JVM here, is where it crashes.
Here's the C++ DLL that invokes the Java class:
// global jvm
static JavaVM *jvm = NULL;
extern"C" JNIEXPORT jint JNICALL Init_JVM( )
{
JNIEnv *env;
JavaVM *vms = NULL;
JavaVMInitArgs vm_args;
JavaVMOption options[1];
char *pszClasspath =newchar[1024];
jint res = 0;
jsize buf_len = 1;
jsize vmsCount = 0;
// builds the classpath string
pszClasspath = build_Classpath();
if (pszClasspath !="")
{
// arguments
options[0].optionString = pszClasspath;
vm_args.version = JNI_VERSION_1_4;
vm_args.options = options;
vm_args.nOptions = 1;
vm_args.ignoreUnrecognized = JNI_TRUE;
// see if there are loaded VMs. If so, use it instead of creating a new one
res = JNI_GetCreatedJavaVMs(&vms, 1, &vmsCount);
// if no errors and 0 VMs are loaded
if(res == 0 && vmsCount == 0)
{
// Create the Java VM
res = JNI_CreateJavaVM(&jvm, (void **)&env, &vm_args);
}
return res;
}
else
{
// Return a non-0. Caller will handle error.
return -1;
}
}
extern"C" JNIEXPORT BSTR JNICALL Convert( )
{
JNIEnv *env;
BSTR bstrRet;
// ********************* THIS IS WHERE IS CRASHES *********************
// Retrieve the env value from the global jvm
if (jvm->AttachCurrentThread((void **)&env, NULL) < 0)
{
// check to see if an exception was thrown
bstrRet = CheckJNIException(env);
}
else
{
// work to invoke Java class
}
return bstrRet;
}

