
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;
public void addNotify() {
super.addNotify();
ref = create();
}
public void removeNotify() {
dispose(ref);
super.removeNotify();
}
native int create();
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