Also the difference between using .NET's P/Invoke (DllImport) interface versus Java's JNI is about as big as can be in terms of developer pain and overhead.
Have a look at JNA. It's about as easy to use as P/Invoke.
Of course Java's days on the desktop are kind of numbered with the various browser and OS vendors getting visibly concerned about the security of the JRE, but that's a different matter.
Unfortunately it's still a huge pain to use JNA with stuff that returns unions (or a pointer to different type depending on the usage context). That makes things like X libraries wrappers really difficult to write in a clean way.