当我从控制台运行我的代码时,它运行正常:创建了jvm并运行我的应用程序。但是,如果我将可执行文件作为Windows服务运行,则JNI_CreateJavaVM将失败并返回-1。 我是否需要在服务中配置某些内容才能使其正常工作?
由于
编辑:添加代码示例
我下载了Microsoft的服务示例,并根据我的需要对其进行了修改。基本上,当服务启动时,它会在一个新线程中运行此函数:
void CWSMService::ServiceWorkerThread(void)
{
// Periodically check if the service is stopping.
wchar_t szMessage[260];
JNIEnv *env = NULL;
JavaVM *vm = NULL;
while (!m_fStopping)
{
jint res;
jclass cls;
jmethodID mid;
res = JNI_CreateJavaVM(&vm, (void**)&env, getVMArgs());
if(res < 0)
{
StringCchPrintf(szMessage, ARRAYSIZE(szMessage), L"Can't create Java VM (%d)", res);
WriteEventLogEntry(szMessage, EVENTLOG_ERROR_TYPE);
break;
}
cls = env->FindClass(JAVA_BOOTSTRAP_CLASS);
if (cls == NULL)
{
StringCchPrintf(szMessage, ARRAYSIZE(szMessage), L"Class not found %s", JAVA_BOOTSTRAP_CLASS_WIDE);
WriteEventLogEntry(szMessage, EVENTLOG_ERROR_TYPE);
vm->DestroyJavaVM();
break;
}
mid = env->GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V");
if (mid == 0)
{
StringCchPrintf(szMessage, ARRAYSIZE(szMessage), L"No main() method in class %s", JAVA_BOOTSTRAP_CLASS_WIDE);
WriteEventLogEntry(szMessage, EVENTLOG_ERROR_TYPE);
vm->DestroyJavaVM();
break;
}
env->CallStaticVoidMethod(cls, mid, getProgramArgs(env));
jthrowable exc = env->ExceptionOccurred();
if (exc)
{
jboolean isCopy = false;
jmethodID toString = env->GetMethodID(env->FindClass("java/lang/Object"), "toString", "()Ljava/lang/String;");
jstring s = (jstring) env->CallObjectMethod(exc, toString);
const char* utf = env->GetStringUTFChars(s, &isCopy);
StringCchPrintf(szMessage, ARRAYSIZE(szMessage), L"Java Exception: %s", utf);
WriteEventLogEntry(szMessage, EVENTLOG_ERROR_TYPE);
env->ReleaseStringUTFChars(s,utf);
vm->DestroyJavaVM();
break;
}
}
if (vm) vm->DestroyJavaVM();
// Signal the stopped event.
SetEvent(m_hStoppedEvent);
Stop();
}
JavaVMInitArgs* CWSMService::getVMArgs()
{
JavaVMInitArgs* vm_args = new JavaVMInitArgs();
JavaVMOption* options = new JavaVMOption[1];
options[0].optionString = "-Djava.class.path=E:\\build_0670_19_00\\jar\\Itamar.jar";
vm_args->version = JNI_VERSION_1_2;
vm_args->options = options;
vm_args->nOptions = 1;
vm_args->ignoreUnrecognized = JNI_TRUE;
return vm_args;
}
当我从Windows服务运行此可执行文件(由我的用户\本地服务运行)时,我在事件日志中收到此错误:
无法创建Java VM(-1)
但是当我从命令行运行它时它会成功并运行java代码。 我尝试使用32位java在32位模式下编译,在64位模式下使用64位java编译它,行为保持不变。
编辑2: 它在工作!! 对于未来可能会遇到类似问题的未来人员的一些注意事项: 1.当你查找一个课程(让我们说 com.mysite.foo.bar )你应该实际上这样称呼: cls = env-&gt; FindClass(“com / mysite / foo / bar”); 2.在类路径中你可以使用双重'\',如: C:\\ com \\ mysite \\ foo \\ bar 或只是 / C:/ com / mysite / foo / bar
在我的情况下,它确实创建了JVM,但由于服务处于while循环中,因此第二次失败。它一开始并没有困扰我,因为我的java程序根本不应该返回,但在我的测试中我使用的程序只打印到屏幕......:/