My tl; Согласно рекомендациям 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 App.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 ...
Код: Выделить всё
std::unique_lock< std::mutex > lock( [censored] );
Это, казалось бы, подтверждает, что проблема, по крайней мере, в некоторой степени связана с этой проблемой или совпадает с ней. Ранее о проблеме сообщалось во многих местах, за одним исключением: когда эта проблема впервые появилась несколько месяцев назад, мы смогли ее исправить, определив _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