Я пытаюсь запустить JVM из моей программы C / Obj C, но у меня есть некоторые проблемы с отображением визуальных элементов, таких как, например, окно, в Catalina.
Часть программы, которая использует невизуальные элементы, т.е. консоль & System.out
работает нормально. Но не отображается какое-либо окно приложения, хотя появляется соответствующий значок Dock, который при нажатии ничего не делает.
Я написал вспомогательную функцию для запуска JVM. В качестве аргументов он имеет
- расположение
libjvm.dylib
- параметров JVM
- размер параметров jvm
- основных аргументов
- размер основных аргументов
- основной класс
Мне кажется, что я что-то упускаю, но не могу понять, что. Есть идеи?
Вот код:
typedef jint (*JNI_CreateJavaVM_f)(JavaVM **, void **, void *);
int launchjvm(char *jvmlib, char **jvmopts, int c_jvmopts, char **args, int c_args, char *mainclass)
{
JavaVM *vm;
JNIEnv *env;
JavaVMInitArgs vm_args;
JavaVMOption options[c_jvmopts];
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
memset(&vm_args, 0, sizeof(vm_args));
vm_args.version = JNI_VERSION_1_8;
vm_args.ignoreUnrecognized = JNI_TRUE;
for (int i = 0; i < c_jvmopts; i++)
options[i].optionString = jvmopts[i];
vm_args.options = options;
vm_args.nOptions = c_jvmopts;
void *lib_handle = dlopen(jvmlib, RTLD_LOCAL | RTLD_LAZY);
if (!lib_handle)
{
printf("[%s] Unable to load library: %s\n", __FILE__, dlerror());
return 1;
}
JNI_CreateJavaVM_f JNI_CreateJavaVM = dlsym(lib_handle, "JNI_CreateJavaVM");
if (!JNI_CreateJavaVM)
{
printf("[%s] Unable to get symbol: %s\n", __FILE__, dlerror());
return 1;
}
jint res = JNI_CreateJavaVM(&vm, (void **)&env, &vm_args);
if (res != JNI_OK)
{
printf("Failed to create Java VM\n");
return res;
}
jclass cls = (*env)->FindClass(env, mainclass);
if (cls == NULL)
{
printf("Failed to find %s class\n", mainclass);
return 1;
}
jmethodID mid = (*env)->GetStaticMethodID(env, cls, "main", "([Ljava/lang/String;)V");
if (mid == NULL)
{
printf("Failed to find main function in class %s\n", mainclass);
return 2;
}
jobjectArray main_args = (*env)->NewObjectArray(env, c_args, (*env)->FindClass(env, "java/lang/String"), NULL);
for(int i = 0 ; i < c_args ; i++)
(*env)->SetObjectArrayElement(env, main_args, i, (*env)->NewStringUTF(env, args[i]));
int result = 0;
(*env)->CallStaticVoidMethod(env, cls, mid, main_args);
if ((*env)->ExceptionOccurred(env)) { // check if an exception occurred
(*env)->ExceptionDescribe(env); // print the stack trace
result = -1;
}
(*vm)->DestroyJavaVM(vm);
[pool drain];
return result;
}