Long, long ago, in a galaxy far, far away, the Java programming language was born. 

Originally intended as an interpreted environment, to run in a "virtual machine", Java's original promise was full portability.  The idea was that, rather than writing programs to an interface presented by an actual machine, as you would with C code, developers would now write to a "virtual machine"  which would be the same regardless of which computer platform it ran on.  Sun even coined a term for this - Write Once, Run Anywhere - which was often called WORA.  Sun itself would provide the Java VM's for various computer platforms, thus effectively commoditizing the variants in hardware.  [Digression #1: Java was so novel and cool, no one noticed in the beginning how strange it was that a company that made all its money selling hardware - Sun - would want to commoditize that very thing.  Nobody except Joel Spolsky, of course. But this was before the dot-com bubble and revenue and business models were things you worried about, later.]  It's funny, we don't hear anyone talking about WORA very much these days....Best I could do is find an article from 2005. Maybe that is because WORA has truly occurred? 

Regardless whether the promise of WORA has been realized or not, at some point, the designers of Java realized that the virtual world of WORA applications was limited, and that people might.... hmmmm......actually want to call into one or more of the platform-specific libraries that had been written during the first, oh, 50 years of programming.  Thus, JNI was born.  JNI is the Java Native Interface, and it is the prescribed way for Java developers to call into platform-specific code. Essentially you write some Java code, and you write some C/C++ code, and you can connect the two via JNI magic.  You need a special JNI compiler and you generate C-header files from Java code, and so on.  Because the bridging code is written in C or C++,  JNI essentially allows you to call out to "anything" from Java.  [side note - Because JNI implies platform-specific modules, apps that use JNI are decidedly not WORA.  ]

Because it allowed developers to expand beyond the confines of the virtual machine, JNI was powerful.  On the other hand, it was also a real pain.  It was just not simple to do (the number of developers that said "I really don't think JNI is that difficult..." indicates how pervasive the view was, that JNI was too difficult) and tool support for JNI has been weak. Debugging is difficult.  [Digression:  Microsoft's C# and VB.NET included nicer facilities and more options for calling existing code (called "un-managed code" in the .NET vernacular.  At one point James Gosling labeled C# and .NET in general as "insecure" because of the ease with which developers could bridge into native code.  I guess the difficulty in writing JNI wrappers was a security feature!  <sarcasm mode="off"/>)]

Lots of JNI frameworks emerged to make the construction of JNI apps simpler and more accessible. JACE, JNIEasy, and a bunch of home-grown ones, too. 

Here is yet another, I just found through a comment on a prior postiingOOJNI for .NET .  It is a framework that allows you to write JNI logic, in a managed .NET language. 

I haven't tried it, but it looks intriguing.  There is a version for .NET 1.1, as well as a version for .NET 2.0. 

Keep in mind, this is for in-process integration of Java and .NET logic.    If you are building enterprise systems, in many cases you are trying to interconnect distributed systems, some of which are implemented in Java, some of which are implemented in .NET, and many of which are implemented in something else entirely.  In those cases, JNI (or OOJNI) is not what you want.  You probably want to take an SOA approach, and model the various large systems as services, and interconnect those services over standards-based web services protocols, like SOAP and its progeny, or even RESTy protocols. 

But if you need in-process integration, OOJNI is yet another option.