ikvmnet / ikvm

A Java Virtual Machine and Bytecode-to-IL Converter for .NET
Other
1.28k stars 121 forks source link

IKVM.Runtime.InternalException : Could not load libjvm #598

Closed san-coder1 closed 1 month ago

san-coder1 commented 1 month ago

I am running my application from Azure Functions. It builds the .dll needed and places it in the bin folder in the Azure Function Runtime folders. Assembly.LoadFile(modelsAssemblyPath); also successfully loads the dll.

It fails with following error during var pipeline = new StanfordCoreNLP(props);

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
   at IKVM.Runtime.LibJava..ctor()
   at IKVM.Runtime.LibJava..cctor()
   End of inner exception
   at IKVM.Runtime.BootstrapClassLoader..ctor(RuntimeContext context)
   at IKVM.Runtime.RuntimeClassLoaderFactory.GetBootstrapClassLoader()
   at IKVM.Runtime.RuntimeClassLoaderFactory.GetClassLoaderWrapper(ClassLoader javaClassLoader)
   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
   at ikvm.runtime.Startup.init()
   at .cctor()
   End of inner exception

I see ikvm folder in and jvm.dll in two places in my Azure Function directory.

c:\home\site\wwwroot\ikvm c:\home\site\wwwroot\bin\ikvm image c:\home\site\wwwroot\bin\ikvm\win-x64\bin> contains the jvm.dll image

I also tried to set ikvm.home.root and ikvm.home, but that did not work either. image

wasabii commented 1 month ago

I really do not know how function apps work.... But is this IIS? Is it using shadow copies? That might be related.

san-coder1 commented 1 month ago

The code works on my local machine (C# solution). It breaks when it is deployed to Azure Functions. And what do you mean by shadow copies? Is there a way to mention where to load this library from?

san-coder1 commented 1 month ago

@wasabii any idea for this? anything I can try?

wasabii commented 1 month ago

I do not. I know nothing of Azure Functions or how they work. Somebody is going to have to do some debugging on their end.

I can say this error has been seen in the past when using IIS shadow copies. Hence why I asked if Azure Functions was IIS.

MarkusSchmidtPro commented 1 month ago

Same here with a .net 8 Console application on a quite fresh Win11 Pro machine. While the same application works on my developer Notebook (I copied the directory with the binaries).

SPOILER

vcruntime140.dll is missing from ikvm\win-x64\bin\

Problem

Stacktrace

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()

Thoughts

I think I found the reason while looking for the differences between my developer notebook and a fresh Windows 11 machine. On the fresh Windows 11 machine vcruntime140.dll cannot be resolved.

image

While this file can be found in many places on my fresh Windows 11 machine (in different versions)

image

this DLL is not in any IKVM resolution path.

Resolution

I have chosen the newest one from any directory on the PC and copied it to ikvm\win-x64\bin\. DONE!

wasabii commented 1 month ago

The requirement for vcruntime140 is unexpected. That shouldn't be there. Need to figure out what is referencing it.

wasabii commented 1 month ago

Okaaay. Looks like some old functions in MSVCRT are still used for various C++ aspects of the OpenJDK code. May be able to work around those.... but for now, the current release still requires VCRT.

MarkusSchmidtPro commented 1 month ago

For me this is ok. I have adjusted the build process to copy the DLL to the bin folder. MarkusS

wasabii commented 1 month ago

Also you could just install the VC++ redistributable.

MarkusSchmidtPro commented 1 month ago

Sure, as long as the app runs on my machine or on a well known target. If I want to publish my app to an unknown audience this complicates the setup, which is zero-copy right now.

Anyways, I am not sure about licensing and distribution of this single DLL. For me: this all is ok.

Others might think different. E g. deploying to Azure with that dependency. .. don't know ...

wasabii commented 1 month ago

Okay. So here's the word:

vcruntime140 is actually still required for some of the C++/C code from OpenJDK. Not really a way to work around it. I could bundle it in the IKVM package. But I think it's probably best to leave that up to the end developer. If you're building an app in IKVM, you need your installer to ensure the VCRedist is up to date. Or include your own copy.

https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170#visual-studio-2015-2017-2019-and-2022

I'm going to go ahead and close this for now. Nothing really to be done about it.

san-coder1 commented 1 month ago

Thanks @wasabii, if we have updates and workaround, we will keep you posted.