Jun 13, 2008

Hello World With JNI

Java Native Interface (JNI) can be used to call native code from your Java application. I needed to call a function from a DLL file. Basically JNI addresses interoperability issues and lets your Java code access legacy system. Here I want to share basic “Hello World” application with you which I developed using JNI.

Starting with Java side, all you need to keep in mind while coding is that you have to declare signature of all legacy methods you need to access. All those methods must be declared with native modifier.

Secondly you need to load native library. That you can achieve using System.loadLibrary(). It will try to load library file from basic operating system library location. e.g. WINDOWS\system32 in windows operating system. If you want to provide a specified location, you can use System.load(String filePath) method.

This is how I code HelloWorld.java.


package com.jay.jni;

public class HelloWorld
{
static
{
System.loadLibrary("TestDll");
}

public static void main(String ar[])
{
System.out.println("Hello world from Java");
HelloWorld t=new HelloWorld();
String strFromDLL = t.inDll();

System.out.println(""+strFromDLL);
}

public native String inDll();

}

Next step is to create a header file. For that you need to run following command

javah -jni com.jay.jni.HelloWorld

This will create a header file with name “com_jay_jni_HelloWorld.h”. Generate header file will be as follow.

/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class com_jay_jni_HelloWorld */

#ifndef _Included_com_jay_jni_HelloWorld
#define _Included_com_jay_jni_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_jay_jni_HelloWorld
* Method: inDll
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_jay_jni_HelloWorld_inDll
(JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

Note the package name in header file. Most of the time people copies code from internet and tries to run program after modification in package and/or class name. You need to be very careful while dealing with JNI.

Now comes native code portion. I created a MFC DLL project in VC++.

Once you create a simple DLL project, add three header files into your project.

1. com_jay_jni_HelloWorld.h
2. jni.h
3. jni_md.h

Second and third can be found in \include folder. Then you need to implement your native function.

For that I created a header file my application TesetDLL with name TestDLL.h. Then I added following code into in it at last.

JNIEXPORT jstring JNICALL Java_com_jay_jni_HelloWorld_inDll (JNIEnv * env, jobject jobj)
{
jstring js = (env)->NewStringUTF("Hello From DLL");
return js;
}

That’s all; I build it and created a DLL. Now all I need to do is put my DLL in system library folder (as I used loadLibrary) and run my program.

Jun 12, 2008

Controlling J2EE Module Depedencies

J2EE Module Dependencies is a critical issue in an enterprise application. You need your one web module to access some resources while prohibiting others. Similar is the case with EJB modules.

Let’s figure it out with Eclipse Web Tools Platform. I consider that you all have ability to create projects and modules in Eclipse; so skipping those steps. I have Eclipse 3.3 with WTP 2.0 M6.

I have created project with following details.

MyProject – Enterprise project

MyEJB_Module – Contains bean class

MyEJBClient_Module – Contains interfaces of EJB, VO, and BeanUtil.

MyWeb_Modules – Holds JSPs, servlets and all presentation tier stuffs.

MyJava_Module – Contains common classes like constants, utilities.

Starting with MyProject, select properties from right click menu. In property dialog, select “J2EE Module Dependencies”. You will find all the modules. Select all as project is dependent on all modules.

Now you can configure dependency of individual module, let’s take an example of web module. In “J2EE Module Dependencies” window, you will find a radio button group which would has by default “Use EJB Client Jars” option selected. That radio button groups defines visibility of EJB jar.

As clients of any EJB should be isolated from bean classes, it is preferable not to select other options where you can define dependencies with EJB jar file. After all, EJB clients should not have any kind of dependencies with EJB jar.

Now here if I select MyEJB_ModuleClient.jar only, MyWeb_Module won’t able to access classes defined in MyJava_Module until you redefine module dependencies.

Similarity you can define dependencies with Utility project, specifically saying third party libraries. You want one module to access one jar and isolate others all you need to do is add library in main project (MyProject in my case) and then configure dependencies of other modules.

This feature takes care of dependencies on behalf of you and let you concentrate on other tasks.