Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Could not load libjvm on Windows servers #623

Open
gintsk opened this issue Nov 25, 2024 · 4 comments
Open

Could not load libjvm on Windows servers #623

gintsk opened this issue Nov 25, 2024 · 4 comments

Comments

@gintsk
Copy link

gintsk commented Nov 25, 2024

Starting from IKVM 8.9.0, the application crashes on startup with a Could not load libjvm exception when initializing IKVM on Windows servers that do not have the Microsoft Visual C++ Redistributables installed.

Minimal repro I use - just call java.lang.System.getenv();
ikvm-test1.zip
The build generates in the output all the necessary IKVM dependencies used by win-x64 - there is nothing missing regarding IKVM runtime dependencies.

Deeper analysis with procmon revealed that the cause of the crash was the absence of VCRUNTIME140.dll, which is a native dependency for loading jvm.dll itself.
image

What is the correct approach for deployment on Windows servers? Is it intended to install Microsoft Visual C++ Redistributables separately as prerequirement for IKVM JVM? Or maybe these dependencies should be distributed with IKVMs JRE images for win RIDs?

C:\test-win-x64>ikvm-test1.exe
Unhandled exception. System.TypeInitializationException: The type initializer for '<Module>' threw an exception.
 ---> System.TypeInitializationException: The type initializer for '<Module>' threw an exception.
 ---> System.TypeInitializationException: The type initializer for 'IKVM.Runtime.LibJava' threw an exception.
 ---> System.TypeInitializationException: The type initializer for 'IKVM.Runtime.LibJvm' threw an exception.
 ---> IKVM.Runtime.InternalException: Could not load libjvm.
   at IKVM.Runtime.LibJvm..ctor()
   at IKVM.Runtime.LibJvm..cctor()
   --- End of inner exception stack trace ---
   at IKVM.Runtime.LibJava..ctor()
   at IKVM.Runtime.LibJava..cctor()
   --- End of inner exception stack trace ---
   at IKVM.Runtime.BootstrapClassLoader..ctor(RuntimeContext context)
   at IKVM.Runtime.RuntimeClassLoaderFactory.GetBootstrapClassLoader()
   at IKVM.Runtime.RuntimeClassLoaderFactory.GetClassLoaderWrapper(ClassLoader javaClassLoader)
   at IKVM.Runtime.RuntimeClassLoader.FromCallerID(CallerID callerID)
   at IKVM.Runtime.JNI.JNIFrame.GetFuncPtr(Object callerID, String clazz, String name, String sig)
   at java.lang.System.initProperties(Properties props)
   at java.lang.System.initializeSystemClass()
   at __<MethodAccessor>__System__initializeSystemClass()
   at IKVM.Runtime.Accessors.Java.Lang.SystemAccessor.InvokeInitializeSystemClass()
   at IKVM.Runtime.JVM.Init()
   at IKVM.Runtime.RuntimeInit.Init()
   at .cctor()
   --- End of inner exception stack trace ---
   at ikvm.runtime.Startup.init()
   at .cctor()
   --- End of inner exception stack trace ---
   at Program.<Main>$(String[] args)
@wasabii
Copy link
Contributor

wasabii commented Nov 25, 2024

As of now it's best of you include it yourself. I wouldn't want to distribute something and conflict with other libraries.

@AliveDevil
Copy link
Collaborator

One option I see would be to dynamically link against UCRT, and statically linking VCRT: https://github.com/microsoft/WindowsAppSDK/blob/main/docs/Coding-Guidelines/HybridCRT.md

@wasabii
Copy link
Contributor

wasabii commented Nov 26, 2024

Interesting. One of my worries with any static linking is the size. Because we didn't just distribute a single DLL, but like 12. And they would all need the static bits.

I'll try to get this working and see if it is acceptable.

@AliveDevil
Copy link
Collaborator

e.g. libjvm would statically link in

N/A, 1 (0x00000001), _CxxThrowException, C:\WINDOWS\system32\VCRUNTIME140.dll, False, None
N/A, 8 (0x00000008), __C_specific_handler, C:\WINDOWS\system32\VCRUNTIME140.dll, False, None
N/A, 27 (0x0000001b), __current_exception, C:\WINDOWS\system32\VCRUNTIME140.dll, False, None
N/A, 28 (0x0000001c), __current_exception_context, C:\WINDOWS\system32\VCRUNTIME140.dll, False, None
N/A, 33 (0x00000021), __std_exception_copy, C:\WINDOWS\system32\VCRUNTIME140.dll, False, None
N/A, 34 (0x00000022), __std_exception_destroy, C:\WINDOWS\system32\VCRUNTIME140.dll, False, None
N/A, 37 (0x00000025), __std_type_info_destroy_list, C:\WINDOWS\system32\VCRUNTIME140.dll, False, None
N/A, 60 (0x0000003c), memcpy, C:\WINDOWS\system32\VCRUNTIME140.dll, False, None
N/A, 62 (0x0000003e), memset, C:\WINDOWS\system32\VCRUNTIME140.dll, False, None

Maybe talking a couple of kilobytes.

Quoted:

[…] This poses a theoretical maximum worst-case static linkage size of ~200KB, but that assumes every symbol in the Standard C/C++ Library is needed. In practice it's a smaller slice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants