2012-05-04 5 views
8

У меня есть приложение для Windows MFC, что:JNI_CreateJavaVM() не каждый второй раз, когда я бегу мое приложение (точно)

(1) Загружает JVM (JNI_CreateJavaVM())

(2) Связывает основную нить виртуальная машина (AttachCurrentThread())

(3) загружает некоторые классы Java и методы (FindClass() и GetMethodID()/GetStaticMethodID())

(4) Регистры некоторые нативные функции обратного вызова для использования Java кода (RegisterNatives())

(5) Отсоединение нить из виртуальной машины Java (DetachCurrentThread())

(6) Уничтожает JVM (DestroyJavaVM())

Все вышеперечисленные функции успеха каждый другой раз я запустить приложение. Я знаю, что они преуспевают, потому что, помимо вышеперечисленного, я взаимодействую с приложением и успешно вызываю статические методы Java, и эти Java-методы успешно вызывают мои собственные обратные вызовы. Мое приложение выходит изящно, и наверняка были выполнены ожидаемые функции Java и собственные обратные вызовы.

Однако каждый раз что я запустить приложение, вызов JNI_CreateJavaVM() выходит из строя (не заселять JavaVM *). Абсолютно ничего не меняется между прогонами приложения. Я просто запускаю его один раз (успешно, даже без делать что-либо, кроме вышеупомянутых 6 шагов), выйти изящно, запустить снова, и он не работает, назад и вперед. Исключений для успеха и неудачи нет. Я могу запускать его десятки раз, и он колеблется точно в любой другой момент между успехом и неудачей на линии JNI_CreateJavaVM().

При необходимости вставьте еще код. Однако я надеюсь, что у кого-то есть представление о том, что я предоставил. (Примечание: это приложение спецификации свойств BCGSoft MFC, хотя я сильно сомневаюсь, что это важно.)

+1

И «каждый раз, когда я запускаю приложение», вы на самом деле означаете, что каждый раз запускаете весь процесс, не так ли? Не только два вызова метода в одном процессе? –

+0

Исправить. В моем случае я запускаю режим Debug и нажимаю F5 в Visual Studio для запуска приложения. Затем я полностью выхожу из приложения. –

+0

Я думаю, что, по крайней мере, отредактируйте и добавьте код, который вызывает JNI_CreateJavaVM, особенно то, как вы заполняли аргументы. –

ответ

4

Похоже, вы работаете в this bug (пересчитано here), что, вероятно, никогда не будет исправлено.

Несмотря на свое название, DestroyJavaVM() фактически не уничтожает JVM. Что он делает, так это сигнализировать JVM о том, что он должен отключиться, но JVM на самом деле ждет, пока все потоки, отличные от основного потока, не остановятся, прежде чем он фактически отключится. Фактически, даже тогда он не полностью очищается после себя, поскольку the documentation заявляет (довольно cryptically): «JDK/JRE по-прежнему не поддерживает разгрузку VM».

Кроме того, меня беспокоит ваш шаг 2: «Прикрепляет основной поток к JVM». Вам не нужно прикреплять поток, который создал JVM для JVM, и вы не можете отсоединить этот поток. Если вы действительно это делаете, возможно, это то, что испортило вашу систему. (Нить, которая создает JVM, - это «Основной» поток JVM. Вам нужно только присоединить/отсоединить другие собственные потоки к JVM, если им нужен доступ к нему.)

Кстати, JNI_CreateJavaVM() возвращает 0 на успех, и вы говорите, что он возвращает 0 «неудачных» раз, поэтому в каком смысле это не удается? Какой JVM (версия, поставщик) вы используете?

+0

Что касается возвращаемого значения 0 - фактически, 'JNI_CreateJavaVM()' не возвращает 0; спасибо, что указали это - это была функция обертки в коде нашего приложения, которая вернула NULL; Я удалил этот текст из своего вопроса. Что касается моего второго шага - я скоро посмотрю на него и опубликую еще один комментарий. –

+0

В дополнение к вышеуказанному комментарию, вопрос: как вы думаете, возможно, что ошибка, о которой вы указали, может применяться даже в моем случае, когда поведение «назад и назад» происходит между * запусками * приложения, а не за один проход? –

+0

@ Да, да, я думаю, что ошибка может применяться, потому что вы запускаете программу из Visual Studio. Если вы прочтете комментарии к ошибке, вы увидите, что у кого-то была такая же проблема из-за того, что Visual Studio повторно использовала поток Debug. –