|

Introduction
For a number of years, I have been developing software for integrating applications written in different platforms. And in my business, I face with interoperability issues: Java and C++, Java and COM, Java and .NET. To solve them, I have developed a number of tools. The last one is the Object-Oriented JNI for .NET (low-level). This is an SDK that wraps the standard Java Native Interface for C++ in .NET classes. Playing with this tool, I have made direct embedding of .NET controls into a Java GUI.
What is Object-Oriented JNI for .NET?
The main idea of Object-Oriented JNI (OOJNI) for .NET is to expose the standard Java Native Interface SDK to .NET programmers as a set of classes. For this, I wrapped all JNI reference types, like jobject, jstring, jclass, etc., with classes:
JObject wraps the jobject reference,
JString keeps the jstring reference and makes all default string conversions Java/.NET and .NET/Java,
JWeakReference wraps the jweak type,
JClass for the jclass reference,
- Java array classes for all primitive Java types and objects. These classes support easy access to Java array items, and can handle and create multi-dimensional Java arrays.
Most standard JNI functions are represented in a managed class ObjectOrientedJNI.JNINativeMethod as static methods. This SDK is compatible with JNI for JDK 1.3.x. The OOJNI SDK also includes a number of useful helpers for easy JNI coding in .NET. All SDK is packed into one module: OOJNIDOTNET.DLL. It is loaded first in a Java process, with the System.load(...) or the System.loadLibrary(...) methods.
An example of direct embedding of .NET contols into a Java GUI
1. Writing Java code for OOJNI
The class MainFrame creates a SWING Frame Window with the FrameWindow object, which is used as a container for the .NET UserControl object and JButton which closes the application. To activate OOJNI in Java, the application loads the module OOJNIDOTNET.DLL first, then the other JNI modules can be loaded (.NET module CSharpInJava.DLL). import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.JButton;
import javax.swing.JFrame;
public class MainFrame extends JFrame {
static{
System.loadLibrary("oojnidotnet");
System.loadLibrary("CSharpInJava");
}
FrameWindow canvas;
JButton okButton;
public MainFrame() {
super("qwerty");
initialize();
}
public void initialize(){
okButton = new JButton();
okButton.setText("Close");
getContentPane().setLayout(new BorderLayout());
getContentPane().add(canvas =
new FrameWindow(), BorderLayout.CENTER);
getContentPane().add(okButton, BorderLayout.SOUTH);
canvas.setBackground(Color.blue);
addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent evt) {
System.exit(0);
}
});
okButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
System.exit(0);
}
});
pack();
setSize(200, 200);
}
public static void main(String args[]) {
new MainFrame().setVisible(true);
}
}
The Java class FrameWindow is used as a container for the .NET UserControl object: import java.awt.Canvas;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
public class FrameWindow extends Canvas {
int ref = 0;
//Called by JVM to create Canvas' Peer
public void addNotify() {
super.addNotify();
ref = create();
}
//Called by JVM to destroy Canvas' Peer
public void removeNotify() {
dispose(ref);
super.removeNotify();
}
//Creates .NET UserControl object and
//returns the reference to it
native int create();
//Destroys .NET object by ref value
native void dispose(int ref);
}
This class keeps a reference to the .NET container object created and the two native methods implemented in CSharpInJava.DLL:
create - creates a .NET UserControl object in FrameWindow on an addNotify call,
dispose - destroys .NET objects in FrameWindow on a removeNotify call.
2. Implementing Java native methods in .NET JNI code
Java native methods can be implemented in .NET code in any class and namespace. The only restrictions are:
- these methods should be static,
- their names must be the same as generated with the javah.exe tool,
- all pointer types (like
JNIEnv*, jobject, jstring, jweak, jclass, etc.) should be substituted with int. using System;
using ObjectOrientedJNI;
using System.Windows.Forms;
namespace CSharpInJava {
public class NativeJavaMethods {
static int Java_FrameWindow_create(int env, int obj) {
if(!JNIEnvHelper.isInitialized())
JNIEnvHelper.init(env);
MyEmbeddedFrame embeddedWindow =
new MyEmbeddedFrame(new JObject(obj));
GlobalReference gref =
new GlobalReference(embeddedWindow, true );
return gref.Reference.ToInt32();
}
static void Java_FrameWindow_dispose(int env, int obj, int peer) {
((MyEmbeddedFrame)new GlobalReference(peer,
false).Object).Dispose();
}
}
}
3. MyEmbeddedFrame class design
MyEmbeddedFrame extends the EmbeddedFrame class from OOJNI (see, P.Foot's example), which embeds .NET controls embedded into a Java application. Add to MyEmbeddedFrame a constructor that gets a JObject instance of Canvas:
public MyEmbeddedFrame(JObject obj) : base(o){}
Implement EmbeddedFrame's method addComponents to initialize the .NET GUI: protected override void addComponents() {
InitializeComponent();
}
In the MS Visual Studio Designer, add to MyEmbeddedFrame, Button and Editor controls (it fills the InitializeComponent method with the code you need).
Points of interest
Now having learnt how to embed .NET controls in a Java GUI, try to write code for embedding ActiveX in Java with .NET. But it is not a simple task as above.
Other resources
- IBM, Sun JDK1.3.x and higher,
- .NET Framework 1.1,
- Object-Oriented JNI for .NET (low-level) is available here.
Thanks
Thanks to a friend of mine, Igor Ladnik, for giving me remarks of material significance.
History
- 05/07/2006 - Initial version.
References
| You must Sign In to use this message board. |
|
| | Msgs 1 to 24 of 24 (Total in Forum: 24) (Refresh) | FirstPrevNext |
|
 |
|
|
Hello Vitaly Well done! It works for me using DotNet 2.0 controls... but not for WPF (DotNet 3.5). I tried to ad an ElementHost into the CSharpInJava control, hosting the WPF UserControl, but I got some Error with this:
# # An unexpected error has been detected by HotSpot Virtual Machine: # # Internal Error (0xe0434f4d), pid=2924, tid=3224 # # Java VM: Java HotSpot(TM) Client VM (1.5.0_06-b05 mixed mode) # Problematic frame: # C [kernel32.dll+0x12a5b] #
Is there already some oojni for WPF and VS2008? Is there another way of using WPF UserControls in Java (swing)?
Thanks and best regards
Reto
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
We developed OOJNI for Native C++ and .NET 1.1,2.0. In near future we plan to make a version for .NET 3.x, and I believe that we should add support for WPF.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
That's good news! I guess you currently don't know when such thing would be available, right?
http://www.codeproject.com/KB/COM/javanet.aspx
I was also thinking to go through a COM layer using JNI. Do you know if this would be feasible? Thanks
Reto
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Excellent example. Hey, i am first time trying this java and c# integration. could you please create any HelloWorld example and post it.So for me and other starters to learn from scracth because HelloWorld is first step to learn anything in programming.
Hope you take this initialtive.
Thanks & Regards, Rajan
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
I have saw in this article that the author goes by the name Vitaly "from ISRAEL", and all this Java with dotnet integration - I know there is this part-Israeli company called Mainsoft which got high rated products for .net java integration and from what I've saw at JAVA communities that it really works well.
Anybody got some review about Mainsoft?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
The product OOJNI for .NET was developed in Javain Ltd (not Mainsoft) and now in use in a number of companies. We developed also a version of this product for C++ environment. But now it is MS Visual C++ dependent. But in future we plan develop a version in ANSI C++ that could be used in other platforms.
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
|
Hello,
the article and the code is very good.
However, I have a problem which I think is related to multithreading used by the embedded control. My C# code (works when called from a pure .net application):
public class MyEmbeddedFrame : UserControl { private System.Windows.Forms.Panel parentPanel; private InkCollector myInkCollector;
public MyEmbeddedFrame() { this.parentPanel = new System.Windows.Forms.Panel(); this.parentPanel.SuspendLayout(); this.SuspendLayout(); this.BackColor = Color.Wheat; this.parentPanel.BackColor = Color.WhiteSmoke;
this.Controls.Add(this.parentPanel); this.Name = "EmbeddedFrame"; this.Size = new System.Drawing.Size(200, 184);
InkCollection_Load(); }
private void InkCollection_Load() { this.myInkCollector = new InkCollector(parentPanel); this.myInkCollector.Enabled = true; } }
InkCollector is a class from Tablet PC SDK used for collection of stylus input. It probably creates its own thread that handles input and paints it on the component.
For this bridge framework, I use exactly the same code - only replace UserControl with EmbeddedFrame, override addComponents() (empty) and call base constructor. However, when I embed it in my Swing frame, the panel handled by InkCollector is transparent and the application hangs up.
Do you have any ideas (for a complete JNI/.net newbie) on how to solve this problem? Thanks in advance.
Konrad Garus
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
The example in this article was built with OOJNI SDK for .NET Framework 1.1. OOJNI SDK for .NET 2.0 (MS VS 2005) with this example is available here[^]
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
 |
|
|
Hi there. I am thinking about a free solution regarding integrating java and .Net, and your project looks to fit all my needs. May I use it with Visual Studio 2005, free of charge? If I may use it, there is something I sould consider? (I am planning to use it with C#).
Thanks,
Inácio Ferrarini.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi, we have different versions of OOJNI SDK for .NET 1.1 and .NET 2.0. For MS VS2003 we also developed Add-In that generates Java class wrappers in C++, MCpp, C#, J# and VB. In near future we will issue the same tool for MS VS2005. Demos of these products are restricted and start with MessageBox at the first call to OOJNI. They do not include support for all JDKs like MS/IBM/SUN 1.1.x-1.6.x. You can use Demos but not for commercial purposes. If you want to have a commercial version (which is not expensive and now we give some discounts) it is available at our site.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
Great article. I am trying to implement your library but I am having a few problems.
The environment: I am trying to load an existing java class and call some of its instance methods from a vb.net application. I have your library installed and working... to a point. I can call shared/static methods. Just need some help with the instance methods.
Example shared call that works:
Dim mathID As Integer Dim jj As JClass ObjectOrientedJNI.JVM.load()
'this calls a static method that returns an integer. jj = JNIEnvHelper.FindClass("org/test/TestJNI") mathID = JNIEnvHelper.GetStaticMethodID(jj, "TestSharedInteger", "()I") Dim res As Integer res = JNIEnvHelper.CallStaticIntMethod(jj, mathID, New Object() {})
ObjectOrientedJNI.JVM.unload()
That is all fine. I get the expected return value in the res variable.
Example of instance method call that does not work:
Dim cls As JClass Dim o As JObject Dim jj As JClass Dim initID As Integer Dim mathID As Integer
ObjectOrientedJNI.JVM.load()
jj = JNIEnvHelper.FindClass("org/test/TestJNI") initID = JNIEnvHelper.GetMethodID(jj, "", "()V") o = JNIEnvHelper.NewObject(jj, initID, New Object() {}) cls = JNIEnvHelper.GetObjectClass(oo) mathID = JNIEnvHelper.GetMethodID(cls , "TestInstanceInteger", "()I") ''''It runs fine until the next line.'''''' res = JNIEnvHelper.CallIntMethod(cls, mathID, New Object() {0}) ObjectOrientedJNI.JVM.unload()
This does not work. It always throws an exception at the res = CallIntMethod line: {"Attempted to read or write protected memory. This is often an indication that other memory is corrupt."} System.AccessViolationException: {"Attempted to read or write protected memory. This is often an indication that other memory is corrupt."} Data: {System.Collections.ListDictionaryInternal} HelpLink: Nothing InnerException: Nothing Message: "Attempted to read or write protected memory. This is often an indication that other memory is corrupt." Source: "oojnidotnet" StackTrace: " at JNIEnv_.CallIntMethodA(JNIEnv_* , _jobject* obj, _jmethodID* methodID, jvalue* args) at jni_helpers.JNIEnvHelper.CallIntMethodA(_jobject* , Int32 , jvalue* ) at ObjectOrientedJNI.JNIEnvHelper.CallIntMethod(JObject obj, Int32 methodID, Object[] args) at JavaHoster1.Form1.Form1_Load(Object sender, EventArgs e) in C:\ \JavaHoster1\Form1.vb:line 49" TargetSite: {System.Reflection.RuntimeMethodInfo}
Any advice would be much appreciated.
Cheers,
Aaron
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
You call JNIEnvHelper.CallIntMethod(cls, mathID, New Object() {0}) for Method mathID = JNIEnvHelper.GetMethodID(cls , "TestInstanceInteger", "()I")
that has no parameters. "New Object() {0}" means that you pass one parameter '0'. As I remember VB to pass empty array as parameters you should create:
New Object(-1) {}
in CShart this looks like
new object[0] or new object[]{}
P.S. Just now I have finished OOJNI Add-In for MS Visual Studio that generates wrappers for C++ (now C++ Generator is available as separate product), managed C++, C#, J#, VB. This package includes a new version of OOJNI for .NET (low-level) library. The current one (you use) has problems with Managed C++ and J#.
The other questions you can send to http://www.javain.com/forum/index.php?board=2
-- modified at 3:49 Tuesday 26th September, 2006
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Thanks,
The string(){0} was a cut and paste error into to forum. Just one of the many attempts to get this to work. On the second note, I tried the string(-1){} and it still didn’t work. It still threw the same protected memory error.
Could you post a complete VB sample that includes a simple java class that has a two instance methods; one that returns a string and one that returns and integer. Then the correct VB code to call these methods and get the returned values.
Thanks and Cheers,
Aaron
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi Aaron, this example runs without problems. Look how to handle Java exceptions. The most OOJNI functions check Java exception and throw .NET exception. Do not forget that OOJNI functions accept JString (not String) and JObject (not Object) as parameters. It is very difficult for me to write VB code as I prefer C#, J# and C++.
Module Module1 Sub Main() Dim clazzSystem As ObjectOrientedJNI.JClass Dim clazzEnum As ObjectOrientedJNI.JClass Dim clazzProps As ObjectOrientedJNI.JClass Dim clazzAnotherProps As ObjectOrientedJNI.JClass Dim enumKeys As ObjectOrientedJNI.JObject Dim getPropertiesID As Integer Dim elementsID As Integer Dim keysID As Integer Dim hasMoreElementsID As Integer Dim nextElementID As Integer Dim propsObject As ObjectOrientedJNI.JObject Dim enumObjects As ObjectOrientedJNI.JObject Dim strKey As ObjectOrientedJNI.JString Dim strProp As ObjectOrientedJNI.JString Dim n As Integer = 0
Try ObjectOrientedJNI.JVM.load()
'Find classes clazzSystem = ObjectOrientedJNI.JNIEnvHelper.FindClass("java/lang/System") clazzEnum = ObjectOrientedJNI.JNIEnvHelper.FindClass("java/util/Enumeration") clazzProps = ObjectOrientedJNI.JNIEnvHelper.FindClass("java/util/Properties") 'Get methods IDs getPropertiesID = ObjectOrientedJNI.JNIEnvHelper.GetStaticMethodID(clazzSystem, "getProperties", "()Ljava/util/Properties;") elementsID = ObjectOrientedJNI.JNIEnvHelper.GetMethodID(clazzProps, "elements", "()Ljava/util/Enumeration;") keysID = ObjectOrientedJNI.JNIEnvHelper.GetMethodID(clazzProps, "keys", "()Ljava/util/Enumeration;") hasMoreElementsID = ObjectOrientedJNI.JNIEnvHelper.GetMethodID(clazzEnum, "hasMoreElements", "()Z") nextElementID = ObjectOrientedJNI.JNIEnvHelper.GetMethodID(clazzEnum, "nextElement", "()Ljava/lang/Object;") 'Get java objects objects needed propsObject = ObjectOrientedJNI.JNIEnvHelper.CallStaticObjectMethod(clazzSystem, getPropertiesID, New Object(-1) {}) enumKeys = ObjectOrientedJNI.JNIEnvHelper.CallObjectMethod(propsObject, keysID, New Object(-1) {}) enumObjects = ObjectOrientedJNI.JNIEnvHelper.CallObjectMethod(propsObject, elementsID, New Object(-1) {})
'Check "GetObjectClass" clazzAnotherProps = ObjectOrientedJNI.JNIEnvHelper.GetObjectClass(propsObject) 'Print Class Name Console.WriteLine(clazzAnotherProps.toString) 'Get Method ID and call this method elementsID = ObjectOrientedJNI.JNIEnvHelper.GetMethodID(clazzAnotherProps, "elements", "()Ljava/util/Enumeration;") enumObjects = ObjectOrientedJNI.JNIEnvHelper.CallObjectMethod(propsObject, elementsID, New Object(-1) {})
'Loop by System properties While ObjectOrientedJNI.JNIEnvHelper.CallBooleanMethod(enumObjects, hasMoreElementsID, New Object(-1) {}) = True 'Get Java strings, for conversion to JString call 'operator function explicitly or 'create JString with Copy Constructor (like in the second line) strKey = ObjectOrientedJNI.JString.op_Implicit(ObjectOrientedJNI.JNIEnvHelper.CallObjectMethod(enumKeys, nextElementID, New Object(-1) {})) strProp = New ObjectOrientedJNI.JString(ObjectOrientedJNI.JNIEnvHelper.CallObjectMethod(enumObjects, nextElementID, New Object(-1) {})) n = n + 1 Console.Write("Property[") Console.Write(n) Console.Write("]:") 'Convert Java String to VB String and print Console.Write(strKey.toString) Console.Write(" = ''") 'Convert Java String to VB String and print Console.Write(strProp.toString) Console.WriteLine(" ''") End While Catch ex As ObjectOrientedJNI.JVMException Console.WriteLine(ex.Message) Catch ex1 As System.Exception Console.WriteLine(ex1.Message) End Try End Sub 'In MCPP and C# this code is very short (all conversions are hidden), 'but in VB and J# this is like above End Module
Regards Vitaly Shelest

-- modified at 2:19 Wednesday 27th September, 2006
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Why would anybody do this? If you're on Windows machine why would you slow it down with Java code?
If your in the other world and using Mono, why would you slow Java down?
Show me the why and the benifits...and the disadvantages, a lot of us probably need to see that before going further with this thought process.
Hammers and nails.
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
If you wrote something with network protocol then you should know that connection and transmission of data with a net system is a bottle-neck of software performance. In common, any Java/.NET bridge does the same as my library but in the most sophisticated way with huge overhead - modules more that 1Mb, network interface in the local machine. Mine is less then 200Kb and use direct calls to methods. So I cannot get your question.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Because maybe you have to mix both technologies
We are facing now access from Sharepoint WebParts to Java dll's...
I mean, sometimes you have to use some tools or products developed in other technologies...
I think the article is really good and interesting ( In a week time, I'll tell you if was useful for our Issue )
Thanks and Regards
Ricardo Casquete
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi Ricardo, there are a number of products for integration of applications/modules written in different technologies. My first company (Composia Ltd.) developed such techology for MS Windows. It allows to integrate application/modules, which source codes are not available (see http://www.composia.com/). In this article I try to prove that .NET may be integrated with Java directly, without mediators.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi Vitaly
I think you misunderstand me.
My answer were not for you, it was for bri189b, becuase he ask... why mix both...
I really enjoyed your Article... really nice.
This week I am on training... but next one I'll make a demo about call Java ddls from dotNet code... I will read more carefully your article and I'll have a look to the link you have posted...
I'll let you know my conclusions...
Thanks and Regards
Ricardo Casquete
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
General News Question Answer Joke Rant Admin
|