bridge between Java and .NET (intraprocess, fast, object oriented, open-source)
This page will be troubleshooting knowledge-base for jni4net. Please contribute.
Process core-dumped, corrupted memory or just can't start it
Ordered by probability.
- Bad choice - jni4net is maybe not 100% fit for your problem. Look at links page for alternatives. If you need to use some Java library from .NET, maybe IKVM will make your life easier. jni4net is very useful if you need real JVM and real CLR. I don't know about any FOSS CLR/C# for JVM.
- Signature changed - You forgot to regenerate and recompile both proxies after you changed method signature.
- It never worked - Did you tried to run samples on this machine ever ? Try it now, if they fail as well, it's the environment, not your code.
- Version checks - Make sure you have expected versions of JVM, CLR and OS.
- PATH and JAVA_HOME - Do they contain proper thing ? Even in your unit test ? And your runtime settings ?
- Architecture - Make sure you have same architecture for JVM and CLR. 32 or 64 bit, do not mix them.
This is particularly difficult on Windows 64-bit. I found 32-bit java.exe of jre 1.5 in my %windows%/system32 directory. Very confusing.
Another problem is running unit tests from VisualStudio + Resharper4, bear in mind VS is 32-bit process.
- Current directory - For best results put all DLLs and JARs into same directory. Make sure it's current directory of the process.
- Proxygen and Versions - Example: you wrapped class from JDK 1.6 and you run under JRE 1.5. Methods are missing. Applies to any library and versions including .NET libraries.
- Security - jni4net runtime requires to run as trusted code. If you run it in sandboxed appdomain or from internet security zone, you need to make the jni4net.n assembly trusted.
Proxygen (as it uses jni4net runtime) needs to run as trusted code. If you run it from shared drive make sure you change your policy.
Another problem may be that you downloaded the distribution zip file and unpacked it via Windows Explorer. The explorer is unfortunatelly smart enough to mark the files unsecure, as they were downloaded from internet. You could select all DLL files and right click properties. Then click unblock button to fix the problem. See here
- ClassLoader - Proxies of CLR objects are by default loaded into system ClassLoader. You could use Bridge.LoadAndRegisterAssemblyFromClassLoader(File, ClassLoader) from Java side and load related j4n.jar into the classLoader of choice.
Missing features and known bugs
- Features - There is lot of missing features for jni4net. If you need some feature, please report it and contribute solution or prototype if you can.
I'm busy man and do this just as a hobby.
- Bugs - There may be bug in jni4net. There may be bug in JNI or in PInvoke. Please report it to us including environment details.
- Package names - All package names of Java classes must have lower-case names as is usual in Java. Capital leters in package names are not supported by jni4net yet.
Pitfalls by design
- Garbage collection - If you create cycle between objects cross VMs boundaries, it will be never reclaimed by GC. That's because collectors don't know about each other.
There is no troubleshooter for that yet. Just be careful what you do.
- Proxy Instances - same real object from home VM could have multiple proxies in the other VM. That's because every transmission creates another proxy.
You should not assume identity by object reference. You should use equals() method to compare objects.
- java.lang.Throwable and system.Exception - these proxies are not inherited from system.Object or java.lang.Object proxies. So you could not put them into collection of proxies of Object easily.
There is IObject interface which is implemented by object as well as by exception. You could use it in collections.
- Application Domains and JVMs - If you have multiple application domains in your process, all of them will find same JNI. jni4net currently binds to default JVM in the process.
- Application Domains and instances - You may need to share same JVM object into two different application domains.
You do it by sending JvmHandle to other domain and duplicating the reference in the other app-domain.
- Address Space - If your address space in 32-bit process is already crowded, it may be a problem to fit another VM in there. Example of such application is Excel with lot of plugins installed.
Still no luck ?