У меня есть собственное приложение, которое запускает JVM и взаимодействует с ней через JNI API. Собственное приложение создает (сложный) объект JVM и передает его в качестве параметра при вызове метода. Проблема в том, что в некоторых случаях при определенных входных данных происходит сбой JVM во время выполнения метода с:
Exception in thread "Thread-1" java.lang.IncompatibleClassChangeError
Я узнал, что это исключение генерируется JVM, когда некоторые несовместимые бинарные изменения были внесены в класс, используемый клиентом, который не знает об изменениях. Однако я не понимаю, как это могло произойти: в моем случае JVM имеет только одну толстую банку в пути к классам. Я не могу найти в нем повторяющиеся классы, а клиентский код всегда компилируется для получения толстой банки.
На «Что вызывает ошибку java.lang.IncompiledClassChangeError?» я обнаружил, что есть еще одна потенциальная причина: метод, вызываемый через JNI с объектами неправильного типа, например. в неправильном порядке. Итак, я добавил динамические проверки с помощью IsInstanceOf, чтобы проверять тип любого объекта, передаваемого в JVM. К сожалению, все проверки проходят успешно.
Как я могу отладить это? У исключения нет сообщения (например, нет сообщения типа «Ожидаемое нестатическое поле ChildClass.message»). Это может указывать на то, что проблема вызвана JNI, а не «более распространенным» случаем несовместимого двоичного изменения в библиотеке.
Пробовал -verbose:class но ничего странного в логе не вижу. Последний загруженный класс кажется обычной лямбда-функцией Scala, ничего странного:
[Loaded a.b.c.FastPrettyPrinter$$$Lambda$457/868352876 from a.b.c.FastPrettyPrinter$]
Есть ли список исчерпывающий или объяснение того, что может вызвать IncompatibleClassChangeError при вызове методов JVM через JNI?
Я пытаюсь -Xcheck:jni, но выполнение становится настолько медленным, что за 1 час программа еще не достигла точки, когда она обычно вызывает исключение.




Попробуйте также
-Xcheck:jni