@rPman

Как понять и исправить EXCEPTION_ACCESS_VIOLATION при вызове jni метода при использовании упаковщика в exe файл javafxpackager и x86_64 версии java?

Занимаюсь задачей разработки установщика приложения java, использующего голосовой движок для синтеза речи rhvoice. Главная цель - исключить требование администраторских прав. Это значит нельзя использовать sapi версию движка, так как для его установки требуется повышение привелегий.

Решение достаточно простое, необходимый код уже есть в проекте rhvoice для android, необходимо внести минимум формальных правок, чтобы собрать jni библиотеку под windows (собираются сразу под обе архитектуры x86 и x86_64).

В общем обе dll собираются, и приложение на java успешно их использует и все работает на обоих архитектурах, если запускать приложение с помощью java виртуальной машины.

Но если собрать полученное приложение (набор jar файлов, данные языковых пакетов rhvoice и собранные dll) с помощью javafxpackager (это штатное приложение javafx для сборки exe версии, которое использует jvm.dll идущее в поставке с java) или тем же packr, то при запуске 64-битной версии возникает исключение (32-битная версия отрабатывает без проблем):
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ff83fa36b2d, pid=110316, tid=0x0000000000019f60
#
# JRE version: OpenJDK Runtime Environment (8.0_201-b09) (build 1.8.0_201-1-ojdkbuild-b09)
# Java VM: OpenJDK 64-Bit Server VM (25.201-b09 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C  [RHVoice.64.dll+0x6b2d]
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
...
Stack: [0x000000dd61600000,0x000000dd61ad0000],  sp=0x000000dd61acf030,  free space=4924k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C  [RHVoice.64.dll+0x6b2d]
C  0x000002990001962e

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  com.github.olga_yakovleva.rhvoice.TTSEngine.doGetVoices()[Lcom/github/olga_yakovleva/rhvoice/VoiceInfo;+0
j  com.github.olga_yakovleva.rhvoice.TTSEngine.getVoices()Ljava/util/List;+1
j  com.github.olga_yakovleva.rhvoice.Test.go()V+17
j  com.github.olga_yakovleva.rhvoice.Test.main([Ljava/lang/String;)V+34
v  ~StubRoutines::call_stub

При использовании разных версих rhvoice ошибка возникает в разных ситуациях, чаще всего почти сразу после вызова первого же jni метода, но если в коде dll rhvoice вставить вывод отладочной информации, видно что код запускается и какое то время выполняется. С некоторыми комбинациями версий у меня выпадала эта же ошибка внутри одной из java dll.

Пробовал разные версии oracle java начиная с 100-ой и до последней. Пробовал последнюю версию openjdk, неофициальный билд под windows - результат идентичный, 32-битная версия работает, а 64-битная падает с исключением.

К сожалению не очень понимаю, как мне выявить причину подобного падения и исправить ошибку, если она есть в коде rhvoice. Я не могу использовать отладчик либо не знаю как настроить окружение для него, полагаю для этого необходимо отладочные версии всего и java и моей библиотеки и т.п.?

p.s. несколько лет назад (в 2014 году) когда я решал эту задачу, 64-битная версия работала на windows 7 и кажется на windows 8. К сожалению собранные тогда dll не работают на windows 10. Попытки подобрать версии компилятора (использовался vs2013, пробовал vs2015 а сейчас vs2017), версии oracle java и даже операционную систему, в которой идет сборка, не увенчались успехом но показали что результат сильно зависит ото всех этих параметров, т.е. критично даже если вести сборку под win7 и запускать под win10.

upd. проблема можно сказать решилась, используя релизный тег rhvoice (прошлогодний релиз) но вопрос о том как в принципе можно отлаживать приложения, запускаемые таким способом,..
  • Вопрос задан
  • 1156 просмотров
Пригласить эксперта
Ответы на вопрос 2
@oldd
Программист, архитектор, тимлидер
Вы не пробовали собирать с помощью Launch4j ?
Ответ написан
@rPman Автор вопроса
Если что эту проблему я решил некоторое время назад, в коде rhvoice обнаружил баг, указатель сохранялся в 4-байтовую переменную (а затем переносился в 8-байтовый лонг java), когда как для 64-битных систем нужно сразу 8 байт.

Разработчикам rhvoice ооб этом сообщили но багу пока они не пофиксили, это тут, long нужно заменить на auto
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы