Closed sanjeev-saxena-us closed 5 months ago
Not exactly sure I understand this..... but generally you should not generate IKVM assemblies and add them to NuGet packages. Use IkvmReference or MavenReference for proper management of Java libraries.
The documentation indicated that the generated dlls are added as a reference to the project (in our case, the lib.csproj nuget pkg)
IkvmReference does not do this. You should be adding IkvmReference in each project that depends upon the libraries. It operates like Reference, and is not transitive.
MavenReference though is transitive.
We are no longer using the nuget approach and have a single app service project. However when we deploy to kubernetes in Azure, we are getting failures such as:
---> System.TypeInitializationException: The type initializer for 'java.io.FileInputStream' 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.io.FileInputStream.initIDs()
Btw, deploying and running in kind locally works just fine; it is an issue in Azure k8s
Are you publishing all the proper content to the docker image, or doing something magic like naot or single file?
All are being included in the docker image.
What is interesting is that building the docker image locally works in both AKS and kind. The docker image built from an Azure pipeline fails in both AKS and kind. We noticed that when comparing the images, there is only 1 dll that is different ie. the app dll.
Our VS solution contains 2 VS projects the app and a lib; the app csproj has a project reference to the lib csproj; the lib csproj has all the IkvmReference items.
We tried dropping the lib project, brought in the code from the lib project into the app project and have all the IkvmReference items in the app's csproj but that resulted in the same issue.
Thoughts?
Unhandled exception. System.TypeInitializationException: The type initializer for '
@wasabii this seems to be a class loading issue as it (via IKVM) creates the class before running a method I assume in the java.io.FileInputStream then we get the above exception. Does this strike you as a build issue or in code with in a K8 cluster?
In your product output, whether in the bin/ directory, or otherwise, is IKVM correctly copying the ikvm/{rid} folders?
There should at least be one ikvm/{rid} directory for the architecture you're targeting. In it, there should be a bin/ and lib/ folder, and the bin/ directory should contain various libraries. Specifically libjvm.so, and libiava.so, for Linux. And those should be ELF files of the appropriate platform.
is there an example docker build file that adds those libs to the container?
Not from me.
The items are supposed to be emitted from dotnet publish. How you get that onto the Docker image is kinda up to you.
Ok but I assume those lib folders are the JRE that needs to be there for runtime class loading for IKVM?
Not really. But they need to be there.
thanks so the JRE does not need to be present to run IKVM got it
IKVM is a JRE. Kinda the point. It's Java classes converted to .NET classes. But it does need those native libraries for different backend implementations of classes sourced from OpenJDK.
good morning @wasabii we built it on a linux box in K8 and its on this folder structure.
We built the app on one of the linux pods that the agent uses (nothing particular about that, just ubuntu). It looks like it generates the so files but places them in a folder called ikvm/
e.g. ikvm/linux-x64/bin:
-rwxr--r-- 1 root root 17 Apr 16 14:52 ikvm.properties -rwxr--r-- 1 root root 1512 Apr 16 15:42 libawt.so -rwxr--r-- 1 root root 128944 Apr 16 15:41 libfdlibm.so -rwxr--r-- 1 root root 383328 Apr 16 15:42 libiava.so -rwxr--r-- 1 root root 33456 Apr 16 15:42 libjsound.so -rwxr--r-- 1 root root 278976 Apr 16 15:42 libjsoundalsa.so -rwxr--r-- 1 root root 142336 Apr 16 15:41 libjvm.so -rwxr--r-- 1 root root 3760 Apr 16 15:42 libmanagement.so -rwxr--r-- 1 root root 468088 Apr 16 15:42 libnet.so -rwxr--r-- 1 root root 262520 Apr 16 15:42 libnio.so -rwxr--r-- 1 root root 484464 Apr 16 15:42 libsunec.so -rwxr--r-- 1 root root 482448 Apr 16 15:42 libunpack.so -rwxr--r-- 1 root root 145960 Apr 16 15:42 libverify.so
Is this in accordance with how it should operate?
Yup that seems fine. So my guess is we link to something on Linux that isn't present on your container.
You can probably get into the container and run ldd on each library to see if it is missing anything.
@wasabii Progress but different errors now
I added an option in the template (in a feature branch), ivkmMigration + ivkmArchitecture that allows specifying to migrate the ivkm files for the specified architecture to the publish folder. Ran this, works, however, now that the .so files are there, getting a little different errors:
Unhandled exception. System.TypeInitializationException: The type initializer for '
Did you make any progrss on this?
I just threw together a test project out of the box using the VS run in container template. Creates a linux container using mcr.microsoft.com/dotnet/aspnet:8.0. It runs IKVM fine. I made zero changes to the Dockerfile.
Thanks for the update. We discovered the root cause => we have .dockerignore file that has "bin" bindings which resulted in the exclusion of the bin folder. We have removed said binding and CI/CD pipeline is now successfully creating the correct docker image and deploying to the pod; the pod is fully functional. Am closing this issue.
Ahhh. Cool. Yeah. Makes sense.
We have created a .net8 library (eg. lib.csproj) that encapsulates the IKVM generated dlls from the jar files. This library is a nuget package in our private DevOps. We have another .net8 app service (eg. app.csproj) that uses the nuget package above. When this app service runs, it throws an exception at start up because it cannot find any of the dlls in the nuget package. The documentation indicated that the generated dlls are added as a reference to the project (in our case, the lib.csproj nuget pkg) but we do not see them in the dependencies of the lib.csproj.
How can we resolve this?