Как разрешить этот конфликт связывания с vcruntime140.dll, поставляемым с JVM?JAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Как разрешить этот конфликт связывания с vcruntime140.dll, поставляемым с JVM?

Сообщение Anonymous »

Моя организация публикует довольно обширную библиотеку на основе C++17 и связанные с ней приложения, а также мы публикуем привязки Java и C# с помощью Swig. Наша библиотека и привязки поддерживают множество разновидностей и версий macOS, Linux и Windows. Мы успешно делали это в течение многих лет без проблем, но столкнулись с небольшой загвоздкой, связанной с файлом vcruntime140.dll, который поставляется с JVM.
Мое понимание рекомендуемых Microsoft лучших практик заключается в том, что вы не должны поставлять среду выполнения VC, а должны поставлять или предоставлять ссылку на установщик среды выполнения VC, позволяя пользователю установить (или уже иметь) среду выполнения в своей системе и получите соответствующие обновления безопасности и исправления ошибок для него от Microsoft. Судя по всему, JVM нарушает эти рекомендации, отправляя файл vcruntime140.dll напрямую (а не только Oracle JVM... похоже, что OpenJDK, Temurin и другие сделали/сделали это). И до сих пор это ничего для нас не сломало.
Но теперь выяснилось, что Microsoft ввела одну или несколько двоичных несовместимостей со средой выполнения VC между версиями 14.31 (поставляемой с JVM) и 14.40 (средой выполнения, установленной на наших сборщиках от Microsoft, с которой связываются все наши библиотеки, привязки и приложения во время сборки). Или несовместимость может быть связана со средой выполнения VC 14.31 и заголовком, предоставленным последней версией компилятора. В любом случае, когда opt-версия нашей библиотеки привязок загружается с помощью Java System.loadLibrary(libName), мы получаем ошибки, препятствующие загрузке библиотеки:

Код: Выделить всё

Unhandled exception at [sensored] (msvcp140.dll) in java.exe: [censored]: Access violation reading location 0x00000000.
#0 msvcp140.dll!mtx_do_lock(_Mtx_internal_imp_t * mtx, const xtime * target) Line 102 C++
#1 [censored].dll![censored]::[censored](void) C++
#2 ...
Строка кода в кадре №1, вызывающая аварийный вызов mtx_do_lock:

Код: Выделить всё

std::unique_lock< std::mutex > lock( [censored] );
У нас нет такой ошибки при загрузке отладочной версии наших привязок, что имеет смысл, поскольку JVM не поставляется с отладочной версией среды выполнения VC. Мы также не получаем ошибок, если (временно) заменяем vcruntime140.dll в каталоге bin JVM копией текущего файла из системных каталогов, но мы не можем попросить наших пользователей сделать это, и неизвестно, какие потенциальные ошибки могут возникнуть в самой JVM.
Похоже, это подтверждает, что проблема, по крайней мере, в некоторой степени связана с этой проблемой, о которой сообщалось ранее, или совпадает с ней. местах, за одним исключением: когда эта проблема впервые возникла несколько месяцев назад, мы смогли ее исправить, определив _DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR, но этот макрос больше не работает с последним обновлением MSVC (что может быть отвлекающим маневром). Мы все еще определяем его во всех тех же местах и ​​даже пытались определить его в дополнительных местах, но безрезультатно. Это больше не предотвращает сбой.
Мы попытались явно загрузить системную библиотеку времени выполнения VC версии 14.40 с помощью System.load( vcRuntimeDLLfile ) перед загрузкой нашей библиотеки, и хотя это удалось (исключений не возникает), она, по-видимому, игнорируется (или, скорее, предпочтительнее более старая версия, загруженная первой), поскольку мы все еще не можем загрузить opt-версию наших привязок. Похоже, что нет способа сообщить базовой системе, что нам нужна более новая версия для нашей библиотеки привязок.
В этой документации Oracle предлагается, чтобы они рекомендовали поставлять версию vcruntime140.dll, необходимую вашей библиотеке, вместе с вашей библиотекой, что нарушает вышеупомянутые рекомендации Microsoft, и другие члены моей команды не решаются сделать это по ряду причин. Однако я начинаю думать, что другого выхода у нас нет. Я предполагаю, что нам нужно будет предоставить его под другим именем (например, vcruntime14.40.dll) в нашем файле Jar и связать его с этим другим именем, чтобы гарантировать, что DLL, предоставленная JVM, не будет выбрана вместо нашей. Ужасно!
Одна мысль, которую я изучаю, - это всегда связывать наши привязки Windows opt с отладочной версией среды выполнения VC, чтобы обходить DLL, предоставляемую JVM. Я пока не уверен, сработает ли это вообще или будет слишком много недостатков/влияния на производительность.
Мы что-то упускаем из виду? Есть ли другой вариант решения этой проблемы? Права ли Microsoft, а разработчики JVM ошибаются? Правы ли разработчики JVM, а Microsoft ошибается? По крайней мере, я понимаю, почему разработчики JVM захотели включить эту DLL, учитывая, что Microsoft нарушает двоичную совместимость — одно обновление Windows может сделать установку Java совершенно бесполезной, если она зависит от среды выполнения системы!

Подробнее здесь: https://stackoverflow.com/questions/789 ... ed-with-th
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»