Programming Tutorials Browser Tutorials Articles Struts Tutorials Hibernate Tutorials

  Tutorial: Embed Java code into your native apps - JavaWorld May 2001

Embed Java code into your native apps - JavaWorld May 2001

Tutorial Details:

Embed Java code into your native apps
Embed Java code into your native apps
By: By Thierry Manfé
Integrate a Java user interface with legacy code on Unix
ike many developers, you want to incorporate new Java technologies into your projects. But currently your code is written in C or in another legacy language, and rewriting your entire application in Java is not a realistic option. In this article you will learn how to embed Java code into your native application and how to integrate GUIs of multiple worlds: Motif, the XToolKit, X Window and OpenGL for Unix, and Swing for Java.
After reading this article you will be able to:
Start a JVM from a legacy application
Create Java objects from a legacy application
Integrate a Swing GUI with the Motif window manager
Call back legacy code from Java using a thread-safe architecture
Where to start?
Consider a simple C program with a Motif user interface. By browsing through its menus, currently the user can create OpenGL windows that contain some simple 3D rendering. You have been asked to add a new menu to this application; you want to implement it using the Swing package from the JDK. The Java Native Interface (JNI) API from the Java Runtime Environment provides you with the tools you need to start a JVM from a C program and accomplish the task at hand. Using that JVM, JNI also allows you to create Java objects and call the objects' methods. Assuming that you have written the code needed for a Java class that implements the required menu (see SwingMenu.java for the full Java code, available for download from Resources ), you now have to access the JNI from the C code to start the JVM and load your class. Listing 1 illustrates those last two tasks:
Listing 1: Start the JVM and load a class
/** File main.c **/
#include
#include
int main (int argc, char *argv[])
{
JNIEnv *env;
JavaVM *jvm;
JavaVMInitArgs vm_args;
JavaVMOption options[3];
int nbOptions;
jint res;
jclass myJavaClass;
jobject javaGUI;
jmethodID constructorID;
char *classPath, *libraryPath;
/** Code to be added here **/
/** Start the Java Virtual Machine **/
classPath = malloc(29);
strcpy(classPath, "-Djava.class.path=/myClassDir"); /* Path of the
SwingManu.class file */
libraryPath = malloc(29);
strcpy(libraryPath, "-Djava.library.path=/myLibDir"); /* Path of
the libNativeMethods.so library */
nbOptions=0;
options[0].optionString = classPath; nbOptions++;
options[1].optionString = libraryPath; nbOptions++;
vm_args.version = JNI_VERSION_1_2; /* Specifies the JNI
version used */
vm_args.options = options;
vm_args.nOptions = nbOptions;
vm_args.ignoreUnrecognized = JNI_TRUE; /* JNI won't
complain about unrecognized options */
res = JNI_CreateJavaVM(&jvm,(void **)&env,&vm_args);
free(classPath);
free(libraryPath);
/*
* Create an instance of the Class SwingMenu.
* Before calling NewObject we must get the constructor
* of the Java class. This constructor must de passed
* as an argument to NewObject.
*/
myJavaClass = (*env)->FindClass(env, "SwingMenu");
constructorID = (*env)->GetMethodID(env,myJavaClass,"",
"()V");
javaGUI = (*env)->NewObject(env,myJavaClass,constructorID);
}
Job done! You are now able to start your application. With a few Java method invocations through JNI you can see your Swing menu on the screen. Below is the picture of your application at startup.
A Motif application using a Swing menu. The knight is drawn using OpenGL.
Allow Swing menu to call back legacy app
Now, what happens if you press the Swing buttons Red or Yellow in the figure above? Nothing yet. You would like the knight to change color, but for it to do so, you need to link your Java code to your legacy application. You must find a way to connect the legacy app with the Swing GUI. The java.awt.event package and JNI help complete that task. The AWT event model defines the ActionListener interface, which listens to the user interactions with the menu. That interface includes the actionPerformed() method, which is called when an action event occurs. The SwingMenu class must implement the ActionListener interface, and it must define the actionPerformed() method. In turn, actionPerformed() calls the changeColour() method that you have declared native in the SwingMenu class. Why native ? Because changeColour() is actually implemented in C -- hence it can easily communicate with your legacy code. The C implementation is located in a dedicated dynamic library that you have named libNativeMethods.so , and that implementation finally calls your legacy function to change the knight's color.
Below is an example featuring a changeColour() method that ensures you can change the knight's color to red. The code below covers the declaration in the Java code, the actionPerformed() method implementation, and the prototyping in C:
Listing 2: Call a C function from Java
// File SwingMenu.java
// Implements the SwingMenu class
import javax.swing.*;
class SwingMenu extends JFrame implements ActionListener {
JButton redButton;
// Declaring a method native
private native void changeColour(int colour);
static { system.loadLibrary("NativeMethods"); }
// Method to create the Java GUI.
public void initGUI(int mainWindow) {
// Create the "Red" button.
redButton = new JButton("Red");
redButton.addActionListener(this);
}
// Method to handle button events.
public void actionPerformed(ActionEvent e) {
String string = e.getActionCommand();
if (string.equals("Red")) { changeColour(1); }
}
}
/** File nativeMethods.c **/
#include
#include
/*
* Functions which is actually called when the changeColour() Java method
is called
*/
JNIEXPORT void JNICALL Java_SwingMenu_changeColour(JNIEnv env, jobject
obj, jint colour)
{
legacyChangeColour((int)colour); /* the legacyChangeColour() function
is defined in our legacy application */
return;
}
jint JNI_Onload(JavaVM *vm, void *reserved)
{
return (JNI_VERSION_1_2);
}
In Listing 2, the file nativeMethods.c implements the methods declared native . You can automatically generate the included file SwingMenu.h by using the javah tool on the SwingMenu class file. You should not modify that file; SwingMenu defines the prototypes of the C functions implementing the Java methods declared native . As you can see in Listing 2, the method name is slightly more complicated than changeColour() .
Note that in the SwingMenu.java file, you must load the library libNativeMethods.so by calling System.loadLibrary() . Performing this call in a static block ensures that the library loads as soon as the Java class loads.
Finally, nativeMethods.c also implements a JNI_Onload() method, which the JVM calls when libNativeMethods.so loads. JNI_Onload() must return the JNI version used by this library. Use JNI 1.2 as specified when starting the JVM from the main program (see Listing 1).
Integrate with the window manager
The window manager is the application that controls the appearance of windows on the screen. This includes stacking order, focus behavior, and the appearance of minimized windows. A Motif application uses a shell widget to communicate with the window manager. That widget accepts the window manager dressing -- borders and buttons that enable the user to move or minimize windows. When a classic application uses many shells independent of one another and the user minimizes the main window, the other shells disappear from the screen. However, if you try this with your application, the Swing shell and its included menu stay on the screen.
To fix that situation, you need to notify the window manager that the shell widget used by the Swing menu is attached to your legacy application's shell. Since X11 window properties are the means of communication with the window manager, you need to change those properties on the underlying window associated with the Swing menu shell. This is classical X Window/Motif programming so I will not provide those details in this article (refer to the attachShell() method in nativeMethods.c available for download in Resources ).
But, you may ask, how do I receive access to the underlying window of the Swing menu shell? Use a new Java 2 API: the AWT Native Interface (NI). This API allows you to access the drawing surface of an AWT Canvas. On Unix, this drawing surface is an X11 window. Once you have access to an X11 window, obtaining the shell widget window, which stands at the top of the window's hierarchy, is somewhat easy. So let's focus on how to obtain the drawing surface using the AWT NI.
Strictly speaking, the AWT NI is not a Java interface; C code calls it. In our case, calls to the AWT NI complete in the attachShell() method, which also handles the work needed to attach the Swing shell to the main shell. Since attachShell() is written in C and called from Java code, it is declared native in the SwingMenu class located in the nativeMethods.c file and built into the libNativeMethods.so library. As a result, on Solaris, you must build libNativeMethods.so with the jre/lib/libjawt.so library, which implements the AWT NI.
As mentioned earlier, the drawing surface is only available for an AWT Canvas, and you did not use AWT Canvas when building your Swing menu; only JButton components included in a JFrame container make up that menu. The solution: create a dummy Canvas and add it into the JFrame . As that Canvas shouldn't interest the user, give it a size of 1 pixel by 1 pixel.
Now let's return to your main purpose: Listing 3 includes the C code that implements the attachShell() method. The AWT Canvas passes as an argument from the Java code:
Listing 3: Obtain the underlying windowing information from an AWT Canvas
/** File nativeMethods.c **/
#include
#include
#include "jawt_md.h"
#include "SwingMenu.h"
/* The Java object canvas must be a java.awt.Canvas. */
JNIEXPORT void JNICALL Java_SwingMenu_attachShell(JNIEnv *env, jobject
obj, j


 

Read Tutorial at: Click here to view the tutorial

Rate Tutorial:
Embed Java code into your native apps - JavaWorld May 2001

View Tutorial:
Embed Java code into your native apps - JavaWorld May 2001

Related Tutorials:

Java Q&A - Java Still Open
Java Q&A - Java Still Open
 
Scripting power saves the day for your Java apps
Scripting power saves the day for your Java apps
 
Enhance your Java application with Java Native Interface (JNI)
Enhance your Java application with Java Native Interface (JNI)
 
JavaMail quick start
JavaMail quick start
 
Bridge the gap between Java and Twain
Bridge the gap between Java and Twain
 
Jini Starter Kit 2.0 tightens Jini's security framework
Jini Starter Kit 2.0 tightens Jini's security framework
 
Using Java Classes in Windows Batch Files
Using Java Classes in Windows Batch Files - a simple approach for system admin Although Java is an ideal language for implementing rich GUI applications, it is equally well-suited for the development of small console-based programs that, in turn, are p
 
Use SWT for data entry
Use SWT for data entry Like many Java programmers, you may have given up on writing client-side window applications. There's a lot of debate about why client-side Java is out of fashion. But most of it boils down to the fact that Java—until now—cou
 
Commons Launcher
The Launcher Component is designed to be a cross platform Java application launcher.
 
Clean Up Your Mess: Managing Temp Files in Java Apps
Clean Up Your Mess: Managing Temp Files in Java Apps Creating and managing temporary files in a Java application can be a little tricky due to some open JVM bugs. Develop a workaround with some custom code and a clever design.
 
Reduce code bloat with XDoclet
Reduce code bloat with XDoclet XDoclet can easily be one of the more versatile cross-technology code-generation tools in your Java programming toolbox. Unfortunately, developers often overlook XDoclet's general utility and use it only when it's bundled a
 
JSP (JavaServer Pages) is a standard for combining Java and HTML to provide dynamic content in web pages.
With JSP, you embed Java code in HTML using special JSP tags similar to HTML tags. You install the JSP page, which has a .jsp extension, into the WebLogic Server document root, just as you would a static HTML page. When WebLogic Server serves a JSP page..
 
JAVASERVER PAGESTM JAVASERVER PAGESTM
JSPTM tag libraries define declarative, modular functionality that can be reused by any JSP page. Tag libraries reduce the necessity to embed large amounts of Java code in JSP pages by moving the functionality provided by the tags into tag implementation
 
JSP Format Bean Library
JSP Format Bean Library is a collection of beans which support Java Server Pages(JSP). JSP allows the HTML developer to embed Java into a page. There are a number of common operations in a scripted page that would be tedious or complex without additional
 
JSP Tutorial
Adding dynamic content via expressionsAs we saw in the previous section, any HTML file can be turned into a JSP file by changing its extension to .jsp. Of course, what makes JSP useful is the ability to embed Java. Put the following text in a file wit
 
Encapsulate reusable functionality in JSP tags
JavaServer Pages (JSP) are a great mechanism for delivering dynamic Web-based content. JSP provides a set of predefined tags, but you can also define your own tag extensions that encapsulate common functionality.
 
Running Wine on the Sun Java Desktop System, Release 2
A BigAdmin reader describes how to install and use Wine, an open source implementation of the Windows API, on the Sun Java Desktop System, Release 2.
 
First Step towards JDBC!
First Step towards JDBC! First Step towards JDBC Introduction T his article introduce you with JDBC and shows you how to create a database application to access the databases. For the shake of simplicity, in very first example Access database and
 
JSP Architecture
JSP Architecture JSP ARCHITECTURE J PS pages are high level extension of servlet and it enable the developers to embed java code in html pages. JSP files are finally compiled into a servlet by the JSP engine. Compiled servlet is used by the engine
 
Getting Started With the PIM APIs
This article provides a code-intensive introductory tutorial to Personal information management (PIM) APIs, JSR 75.
 
Site navigation
 

 

Send your comments, Suggestions or Queries regarding this site at roseindia_net@yahoo.com.

Copyright © 2006. All rights reserved.