Мое понимание рекомендуемых 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 ...
Код: Выделить всё
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
Мобильная версия