Что вызывает IncompatableClassChangeError при вызове методов через JNI?

У меня есть собственное приложение, которое запускает 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

apangin 01.04.2019 06:16

Я пытаюсь -Xcheck:jni, но выполнение становится настолько медленным, что за 1 час программа еще не достигла точки, когда она обычно вызывает исключение.

Federico 01.04.2019 11:01
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
2
254
0

Другие вопросы по теме