Easy to Learn Java: Programming Articles, Examples and Tips

Start with Java in a few days with Java Lessons or Lectures

Home

Code Examples

Java Tools

More Java Tools!

Java Forum

All Java Tips

Books

Submit News
Search the site here...
Search...
 
Search the JavaFAQ.nu
1000 Java Tips ebook

1000 Java Tips - Click here for the high resolution copy!1000 Java Tips - Click here for the high resolution copy!

Java Screensaver, take it here

Free "1000 Java Tips" eBook is here! It is huge collection of big and small Java programming articles and tips. Please take your copy here.

Take your copy of free "Java Technology Screensaver"!.

Easy Learn Java: Programming Articles, Examples and Tips - Page 468


Previous 1060 Stories (530 Pages, 2 Per Page) Next

Native From Java: Java code example

Go to all tips in Java Code Examples

Native call from Java: These samples working illustrate how to call a native library from within Java.

It also includes a sample that attempts a simple performance (speed) comparison between the pure native, pure Java and JNI implementation.

You can find two versions:
- Native call from Java program to C program and
- Native call from Java program to C++ program

C version:


JNISamples.c

Code:

#include <jni.h>
#include "JNISamples.h"
#include <stdio.h>

static void printString(JNIEnv *env, jstring jstr);

JNIEXPORT void JNICALL Java_JNISamples_syncNativeMethod (JNIEnv *env, jobject obj, jobject syncObj)
{
   printf("Inside synchronized native method\n");
   (*env)->MonitorEnter(env, syncObj);
   printf("After synchronizing syncObj\n");
   (*env)->MonitorExit(env, syncObj);
   printf("After releasing syncObj\n");
   /*
   The functions Object.wait, Object.notify, and Object.notifyAll provide
   another useful thread synchronization mechanism. While the JNI does not
   directly support these functions, a native method can always follow the
   JNI method call mechanism to invoke them.
   */
}

JNIEXPORT void JNICALL Java_JNISamples_nativeCatchThrow (JNIEnv *env, jobject obj)
{
   jclass cls = (*env)->GetObjectClass(env, obj);
   jmethodID mid = (*env)->GetMethodID(env, cls, "javaCatchThrow", "()V");
   jthrowable exc;
   jclass newException;

   if(0 == mid)
   {
      printf("Error obtaining method id\n");
      return;
   }

   (*env)->CallVoidMethod(env, obj, mid);
   exc = (*env)->ExceptionOccurred(env);

   if(exc)
   {
      /*
      We don't do much with the exception, except that we print a debug message
      using ExceptionDescribe, clear it, and throw a new exception.
      */
      /*
      It is extremely important to check, handle, and clear the pending exception
      before calling subsequent JNI functions. Calling arbitrary JNI functions with
      a pending exception may lead to unexpected results. You can safely call only
      a small number of JNI functions when there is a pending exception. These
      functions are ExceptionOccurred, ExceptionDescribe, and ExceptionClear.
      */

      (*env)->ExceptionDescribe(env);
       (*env)->ExceptionClear(env);
   }

   newException = (*env)->FindClass(env, "java/lang/IllegalArgumentException");
   if (newException == 0)
   {
      /* Unable to find the new exception class, give up. */
      printf("Error finding the new exception class\n");
       return;
   }

   (*env)->ThrowNew(env, newException, "IllegalArgumentException thrown from C code");
}

JNIEXPORT void JNICALL Java_JNISamples_fieldAccess (JNIEnv *env, jobject obj)
{
   jfieldID fid;
   jstring jstr;
   const char *str;
   jint iStaticIntValue;
   jclass cls = (*env)->GetObjectClass(env, obj);

   fid = (*env)->GetStaticFieldID(env, cls, "iStaticIntFld", "I");
   if(0 == fid)
   {
      printf("Error getting fid for iStaticIntFld\n");
      return;
   }
   iStaticIntValue = (*env)->GetStaticIntField(env, cls, fid);
   printf("iStaticIntValue=%d\n", iStaticIntValue);
   (*env)->SetStaticIntField(env, cls, fid, 200);

   fid = (*env)->GetFieldID(env, cls, "sStringFld", "Ljava/lang/String;");
   if(0 == fid)
   {
      printf("Error getting fid for sStringFld\n");
      return;
   }
   jstr = (*env)->GetObjectField(env, obj, fid);
   printString(env, jstr);

   jstr = (*env)->NewStringUTF(env, "NewString");
   (*env)->SetObjectField(env, obj, fid, jstr);
}


JNIEXPORT void JNICALL Java_JNISamples_nativeMethod (JNIEnv *env, jobject obj, jint iDepth)
{
   jclass cls = (*env)->GetObjectClass(env, obj);
   static jmethodID method = 0;

   /*
   Method ID is valid only for as long as the class
   from which it is derived is not unloaded.
   Obtaining a method ID is a relatively expensive operation.

   Use NewGlobalRef to create a global ref in native code to
   prevent the class from being garbage collected.
   You MUST use DeleteGlobalRef to delete the global reference.

   Use DeleteLocalRef to delete a local ref to release mem immediately.
   */
   if(0 == method)
   {
      method = (*env)->GetMethodID(env, cls, "callback", "(I)V");
   }

   if (method == 0)
   {
      printf("Could not get method callback(I)V\n");
      return;
   }

   printf("In C, depth = %d, about to enter Java\n", iDepth);
   (*env)->CallVoidMethod(env, obj, method, iDepth);
   printf("In C, depth = %d, back from Java\n", iDepth);
}

JNIEXPORT jint JNICALL Java_JNISamples_stringArrAccess(JNIEnv *env, jobject obj, jobjectArray asArr)
{
   int iIndex;
   jsize len = (*env)->GetArrayLength(env, asArr);

   for(iIndex=0; iIndex < len; iIndex++)
   {
      jstring jstr = (*env)->GetObjectArrayElement(env, asArr, iIndex);
      printString(env, jstr);
      /* explicitly releasing to assist garbage collection, though not required */
      (*env)->DeleteLocalRef(env, jstr);
   }

   return len;
}

JNIEXPORT jintArray JNICALL Java_JNISamples_intArrAccess (JNIEnv *env, jobject obj, jintArray aiArr)
{
   int i, sum = 0;
   jintArray aiRet;
   jint *retBody;

   jsize len = (*env)->GetArrayLength(env, aiArr);
   jint *body = (*env)->GetIntArrayElements(env, aiArr, 0);
   /* to copy a region of the array only, use Get/Set<type>ArrayRegion functions */

   for (i=0; i<len; i++)
   {
      sum += body[i];
      body[i]++;
   }

   aiRet = (*env)->NewIntArray(env, len);
   retBody = (*env)->GetIntArrayElements(env, aiRet, 0);

   for (i=0; i<len; i++)
   {
      retBody[i] = body[i];
   }

   (*env)->ReleaseIntArrayElements(env, aiArr, body, 0);
   (*env)->ReleaseIntArrayElements(env, aiRet, retBody, 0);

   return aiRet;   
}


JNIEXPORT jstring JNICALL Java_JNISamples_stringAccess (JNIEnv *env, jobject obj, jstring prompt)
{
   char buf[128];
   const char * str = (*env)->GetStringUTFChars(env, prompt, 0);

   printf("Inside Native: %s\n", str);
   sprintf(buf, "Hello [%s][%d][%d]",
         str,
         (*env)->GetStringUTFLength(env, prompt),
         (*env)->GetStringLength(env, prompt));
   (*env)->ReleaseStringUTFChars(env, prompt, str);

   return (*env)->NewStringUTF(env, buf);
}

static void printString(JNIEnv *env, jstring jstr)
{
   const char * str = (*env)->GetStringUTFChars(env, jstr, 0);
   printf("%s\n", str);
   (*env)->ReleaseStringUTFChars(env, jstr, str);
}



JNISamples.h
Code:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class JNISamples */

#ifndef _Included_JNISamples
#define _Included_JNISamples
#ifdef __cplusplus
extern "C" {
#endif
/* Inaccessible static: iStaticIntFld */
/*
 * Class:     JNISamples
 * Method:    fieldAccess
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_JNISamples_fieldAccess
  (JNIEnv *, jobject);

/*
 * Class:     JNISamples
 * Method:    intArrAccess
 * Signature: ([I)[I
 */
JNIEXPORT jintArray JNICALL Java_JNISamples_intArrAccess
  (JNIEnv *, jobject, jintArray);

/*
 * Class:     JNISamples
 * Method:    nativeCatchThrow
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_JNISamples_nativeCatchThrow
  (JNIEnv *, jobject);

/*
 * Class:     JNISamples
 * Method:    nativeMethod
 * Signature: (I)V
 */
JNIEXPORT void JNICALL Java_JNISamples_nativeMethod
  (JNIEnv *, jobject, jint);

/*
 * Class:     JNISamples
 * Method:    stringAccess
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_JNISamples_stringAccess
  (JNIEnv *, jobject, jstring);

/*
 * Class:     JNISamples
 * Method:    stringArrAccess
 * Signature: ([Ljava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_JNISamples_stringArrAccess
  (JNIEnv *, jobject, jobjectArray);

/*
 * Class:     JNISamples
 * Method:    syncNativeMethod
 * Signature: (Ljava/lang/Object;)V
 */
JNIEXPORT void JNICALL Java_JNISamples_syncNativeMethod
  (JNIEnv *, jobject, jobject);

#ifdef __cplusplus
}
#endif
#endif



JNISamples.java
Code:


public class JNISamples
{
   private native String stringAccess(String sStr);
   private native int [] intArrAccess(int [] aiInp);
   private native int stringArrAccess(String [] asInp);
   private native void nativeMethod(int iDepth);
   private synchronized native void syncNativeMethod(Object oSync);
   private native void fieldAccess();
   private native void nativeCatchThrow() throws IllegalArgumentException;

   static
   {
      System.loadLibrary("JNISamples");
   }

   static int iStaticIntFld;
   String sStringFld;

   public static void main(String [] args)
   {
      JNISamples sample = new JNISamples();

      System.out.println("String access test");
      sample.doString();
      System.out.println("int array test");
      sample.doIntArray();
      System.out.println("String array test");
      sample.doStrArray();
      System.out.println("Callback test");
      sample.callback(0);
      System.out.println("Field access test");
      sample.doFldAccess();
      System.out.println("Native exception catch and throw test");
      try
      {
         sample.nativeCatchThrow();
      }
      catch(IllegalArgumentException iae)
      {
         iae.printStackTrace();
      }
      System.out.println("Synchronized Native Methods");
      sample.syncNativeMethod(new Object());
      System.out.println("Success!");
   }

   private void javaCatchThrow() throws NullPointerException
   {
      throw new NullPointerException("Null pointer exception thrown in javaCatchThrow");
   }

   private void doFldAccess()
   {
      iStaticIntFld = 100;
      sStringFld = "sStringFld";

      fieldAccess();

      System.out.println("In Java");
      System.out.println("iStaticIntFld = " + iStaticIntFld);
      System.out.println("sStringFld = " + sStringFld);
   }

   private void doString()
   {
      String sRet = stringAccess("String test");
      System.out.println(sRet);
   }

   private void doStrArray()
   {
      String [] asInp = new String[10];
      int iIndex, iLen;

      for(iIndex=0; iIndex<10; iIndex++)
      {
         asInp[iIndex] = "String: " + Integer.toString(iIndex);
      }

      iLen = stringArrAccess(asInp);

      System.out.println("String array size: " + iLen);
   }

   private void doIntArray()
   {
      int [] aiInp = new int[10];
      int iIndex;

      for(iIndex=0; iIndex<10; iIndex++)
      {
         aiInp[iIndex] = iIndex;
      }

      int [] aiOut = intArrAccess(aiInp);

      System.out.print("Int array: {");
      for(iIndex=0; iIndex<10; iIndex++)
      {
         System.out.print(aiInp[iIndex] + ", ");
      }
      System.out.println("}");
   }

   private void callback(int iDepth)
   {
      System.out.println("In Java callback. Depth=" + iDepth);
      if(5 > iDepth)
      {
         nativeMethod(iDepth + 1);
      }
      else
      {
         System.out.println("Stopping recursion");
      }
   }
}




makefile
Code:

#SOLARIS
#---------------
#INCFLAGS=-I/usr/java1.2/include -I/usr/java1.2/include/solaris
#CC=cc
#CXX=CC
#LINK=ld
#KPIC_COMPILE=-KPIC
#KPIC_LINK=-G

#DIGITAL OSF
#---------------
INCFLAGS=-I/usr/opt/java122/include -I/usr/opt/java122/include/alpha -pthread
CC=cc
CXX=cxx
LINK=cc
KPIC_COMPILE=
KPIC_LINK=-shared

all : libJNISamples.so JNISamples.class
   echo "All done"

JNISamples.class : JNISamples.java
   javac JNISamples.java

JNISamples.h : JNISamples.class
   javah -jni JNISamples

libJNISamples.so : JNISamples.o
   ${LINK} ${KPIC_LINK} -o libJNISamples.so JNISamples.o

JNISamples.o : JNISamples.c JNISamples.h
   ${CC} ${KPIC_COMPILE} -c JNISamples.c ${INCFLAGS}


C++ version:

JNISamples.cpp
Code:

#include <jni.h>
#include "JNISamples.h"
#include <iostream.h>

static void printString(JNIEnv *env, jstring jstr);

JNIEXPORT void JNICALL Java_JNISamples_syncNativeMethod (JNIEnv *env, jobject obj, jobject syncObj)
{
   cout << "Inside synchronized native method\n";
   env->MonitorEnter(syncObj);
   cout << "After synchronizing syncObj\n";
   env->MonitorExit(syncObj);
   cout << "After releasing syncObj\n";
   /*
   The functions Object.wait, Object.notify, and Object.notifyAll provide
   another useful thread synchronization mechanism. While the JNI does not
   directly support these functions, a native method can always follow the
   JNI method call mechanism to invoke them.
   */
}

JNIEXPORT void JNICALL Java_JNISamples_nativeCatchThrow (JNIEnv *env, jobject obj)
{
   jclass cls = env->GetObjectClass(obj);
   jmethodID mid = env->GetMethodID(cls, "javaCatchThrow", "()V");
   jthrowable exc;
   jclass newException;

   if(0 == mid)
   {
      cout << "Error obtaining method id\n";
      return;
   }

   env->CallVoidMethod(obj, mid);
   exc = env->ExceptionOccurred();

   if(exc)
   {
      /*
      We don't do much with the exception, except that we print a debug message
      using ExceptionDescribe, clear it, and throw a new exception.
      */
      /*
      It is extremely important to check, handle, and clear the pending exception
      before calling subsequent JNI functions. Calling arbitrary JNI functions with
      a pending exception may lead to unexpected results. You can safely call only
      a small number of JNI functions when there is a pending exception. These
      functions are ExceptionOccurred, ExceptionDescribe, and ExceptionClear.
      */

      env->ExceptionDescribe();
       env->ExceptionClear();
   }

   newException = env->FindClass("java/lang/IllegalArgumentException");
   if (newException == 0)
   {
      /* Unable to find the new exception class, give up. */
      cout << "Error finding the new exception class\n";
       return;
   }

   env->ThrowNew(newException, "IllegalArgumentException thrown from C code");
}

JNIEXPORT void JNICALL Java_JNISamples_fieldAccess (JNIEnv *env, jobject obj)
{
   jfieldID fid;
   jstring jstr;
   const char *str;
   jint iStaticIntValue;
   jclass cls = env->GetObjectClass(obj);

   fid = env->GetStaticFieldID(cls, "iStaticIntFld", "I");
   if(0 == fid)
   {
      cout << "Error getting fid for iStaticIntFld\n";
      return;
   }
   iStaticIntValue = env->GetStaticIntField(cls, fid);
   cout << "iStaticIntValue=" << iStaticIntValue << "\n";
   env->SetStaticIntField(cls, fid, 200);

   fid = env->GetFieldID(cls, "sStringFld", "Ljava/lang/String;");
   if(0 == fid)
   {
      cout << "Error getting fid for sStringFld\n";
      return;
   }
   jstr = (jstring)env->GetObjectField(obj, fid);
   printString(env, jstr);

   jstr = env->NewStringUTF("NewString");
   env->SetObjectField(obj, fid, jstr);
}


JNIEXPORT void JNICALL Java_JNISamples_nativeMethod (JNIEnv *env, jobject obj, jint iDepth)
{
   jclass cls = env->GetObjectClass(obj);
   static jmethodID method = 0;

   /*
   Method ID is valid only for as long as the class
   from which it is derived is not unloaded.
   Obtaining a method ID is a relatively expensive operation.

   Use NewGlobalRef to create a global ref in native code to
   prevent the class from being garbage collected.
   You MUST use DeleteGlobalRef to delete the global reference.

   Use DeleteLocalRef to delete a local ref to release mem immediately.
   */
   if(0 == method)
   {
      method = env->GetMethodID(cls, "callback", "(I)V");
   }

   if (method == 0)
   {
      cout << "Could not get method callback(I)V\n";
      return;
   }

   cout << "In C, depth = " << iDepth << "about to enter Java\n";
   env->CallVoidMethod(obj, method, iDepth);
   cout << "In C, depth = " << iDepth << ", back from Java\n";
}

JNIEXPORT jint JNICALL Java_JNISamples_stringArrAccess(JNIEnv *env, jobject obj, jobjectArray asArr)
{
   int iIndex;
   jsize len = env->GetArrayLength(asArr);

   for(iIndex=0; iIndex < len; iIndex++)
   {
      jstring jstr = (jstring)env->GetObjectArrayElement(asArr, iIndex);
      printString(env, jstr);
      /* explicitly releasing to assist garbage collection, though not required */
      env->DeleteLocalRef(jstr);
   }

   return len;
}

JNIEXPORT jintArray JNICALL Java_JNISamples_intArrAccess (JNIEnv *env, jobject obj, jintArray aiArr)
{
   int i, sum = 0;
   jintArray aiRet;
   jint *retBody;

   jsize len = env->GetArrayLength(aiArr);
   jint *body = env->GetIntArrayElements(aiArr, 0);
   /* to copy a region of the array only, use Get/Set<type>ArrayRegion functions */

   for (i=0; i<len; i++)
   {
      sum += body[i];
      body[i]++;
   }

   aiRet = env->NewIntArray(len);
   retBody = env->GetIntArrayElements(aiRet, 0);

   for (i=0; i<len; i++)
   {
      retBody[i] = body[i];
   }

   env->ReleaseIntArrayElements(aiArr, body, 0);
   env->ReleaseIntArrayElements(aiRet, retBody, 0);

   return aiRet;   
}


JNIEXPORT jstring JNICALL Java_JNISamples_stringAccess (JNIEnv *env, jobject obj, jstring prompt)
{
   char buf[128];
   const char * str = env->GetStringUTFChars(prompt, 0);

   cout << "Inside Native: " << str << "\n";
   sprintf(buf, "Hello [%s][%d][%d]",
         str,
         env->GetStringUTFLength(prompt),
         env->GetStringLength(prompt));
   env->ReleaseStringUTFChars(prompt, str);

   return env->NewStringUTF(buf);
}

static void printString(JNIEnv *env, jstring jstr)
{
   const char * str = env->GetStringUTFChars(jstr, 0);
   cout << str << "\n";
   env->ReleaseStringUTFChars(jstr, str);
}




JNISamples.h
Code:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class JNISamples */

#ifndef _Included_JNISamples
#define _Included_JNISamples
#ifdef __cplusplus
extern "C" {
#endif
/* Inaccessible static: iStaticIntFld */
/*
 * Class:     JNISamples
 * Method:    fieldAccess
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_JNISamples_fieldAccess
  (JNIEnv *, jobject);

/*
 * Class:     JNISamples
 * Method:    intArrAccess
 * Signature: ([I)[I
 */
JNIEXPORT jintArray JNICALL Java_JNISamples_intArrAccess
  (JNIEnv *, jobject, jintArray);

/*
 * Class:     JNISamples
 * Method:    nativeCatchThrow
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_JNISamples_nativeCatchThrow
  (JNIEnv *, jobject);

/*
 * Class:     JNISamples
 * Method:    nativeMethod
 * Signature: (I)V
 */
JNIEXPORT void JNICALL Java_JNISamples_nativeMethod
  (JNIEnv *, jobject, jint);

/*
 * Class:     JNISamples
 * Method:    stringAccess
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_JNISamples_stringAccess
  (JNIEnv *, jobject, jstring);

/*
 * Class:     JNISamples
 * Method:    stringArrAccess
 * Signature: ([Ljava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_JNISamples_stringArrAccess
  (JNIEnv *, jobject, jobjectArray);

/*
 * Class:     JNISamples
 * Method:    syncNativeMethod
 * Signature: (Ljava/lang/Object;)V
 */
JNIEXPORT void JNICALL Java_JNISamples_syncNativeMethod
  (JNIEnv *, jobject, jobject);

#ifdef __cplusplus
}
#endif
#endif


JNISamples.java
Code:


public class JNISamples
{
   private native String stringAccess(String sStr);
   private native int [] intArrAccess(int [] aiInp);
   private native int stringArrAccess(String [] asInp);
   private native void nativeMethod(int iDepth);
   private synchronized native void syncNativeMethod(Object oSync);
   private native void fieldAccess();
   private native void nativeCatchThrow() throws IllegalArgumentException;

   static
   {
      System.loadLibrary("JNISamples");
   }

   static int iStaticIntFld;
   String sStringFld;

   public static void main(String [] args)
   {
      JNISamples sample = new JNISamples();

      System.out.println("String access test");
      sample.doString();
      System.out.println("int array test");
      sample.doIntArray();
      System.out.println("String array test");
      sample.doStrArray();
      System.out.println("Callback test");
      sample.callback(0);
      System.out.println("Field access test");
      sample.doFldAccess();
      System.out.println("Native exception catch and throw test");
      try
      {
         sample.nativeCatchThrow();
      }
      catch(IllegalArgumentException iae)
      {
         iae.printStackTrace();
      }
      System.out.println("Synchronized Native Methods");
      sample.syncNativeMethod(new Object());
      System.out.println("Success!");
   }

   private void javaCatchThrow() throws NullPointerException
   {
      throw new NullPointerException("Null pointer exception thrown in javaCatchThrow");
   }

   private void doFldAccess()
   {
      iStaticIntFld = 100;
      sStringFld = "sStringFld";

      fieldAccess();

      System.out.println("In Java");
      System.out.println("iStaticIntFld = " + iStaticIntFld);
      System.out.println("sStringFld = " + sStringFld);
   }

   private void doString()
   {
      String sRet = stringAccess("String test");
      System.out.println(sRet);
   }

   private void doStrArray()
   {
      String [] asInp = new String[10];
      int iIndex, iLen;

      for(iIndex=0; iIndex<10; iIndex++)
      {
         asInp[iIndex] = "String: " + Integer.toString(iIndex);
      }

      iLen = stringArrAccess(asInp);

      System.out.println("String array size: " + iLen);
   }

   private void doIntArray()
   {
      int [] aiInp = new int[10];
      int iIndex;

      for(iIndex=0; iIndex<10; iIndex++)
      {
         aiInp[iIndex] = iIndex;
      }

      int [] aiOut = intArrAccess(aiInp);

      System.out.print("Int array: {");
      for(iIndex=0; iIndex<10; iIndex++)
      {
         System.out.print(aiInp[iIndex] + ", ");
      }
      System.out.println("}");
   }

   private void callback(int iDepth)
   {
      System.out.println("In Java callback. Depth=" + iDepth);
      if(5 > iDepth)
      {
         nativeMethod(iDepth + 1);
      }
      else
      {
         System.out.println("Stopping recursion");
      }
   }
}



makefile
Code:


all : libJNISamples.so JNISamples.class
   echo "All done"

JNISamples.class : JNISamples.java
   javac JNISamples.java

JNISamples.h : JNISamples.class
   javah -jni JNISamples

libJNISamples.so : JNISamples.o
   cxx -shared -o libJNISamples.so JNISamples.o

JNISamples.o : JNISamples.cpp JNISamples.h
   cxx -c JNISamples.cpp -I/usr/opt/java122/include -I/usr/opt/java122/include/alpha -pthread



21204 bytes more | comments? | Printer Friendly Page  Send to a Friend | Score: 0
Posted by Javaaddict on Wednesday, August 16, 2006 (00:00:00) (7672 reads)

Ready Java example: Embed JVM into native code.

Go to all tips in Java Code Examples

Today we added a collection of sample JNI (Java Native Interace) programs. The ideas are mostly taken from the Sun Java tutorial.

EmbeddingJVM : This code sample illustrates how to embed and call the JVM from a native program.


Code:



/* JNIEmbed.c */

/**
 * Invoking the Java Virtual Machine
 * ---------------------------------
 *
 * The JDK ships the Java Virtual Machine as a shared library
 * (or dynamic link library on Win32). You can embed the Java
 * Virtual Machine into your native application by linking
 * the native application with the shared library.
 *
 * The JNI supports an Invocation API that allows you to load,
 * initialize, and invoke the Java Virtual Machine. Indeed,
 * the normal way of starting the Java interpreter, java, is
 * no more than a simple C program that parses the command line
 * arguments and invokes the Java Virtual Machine through the
 * Invocation API.
 *
 * This program is an implementation of the lessons in the Sun
 * Java Tutorial. Though it will require only minor changes to
 * run this on multiple platforms, currently this has been
 * developed and tested on Windows 2000.
 *
 * Author: Tanmay K. M.
 * http://tanmaykm.tripod.com/
 */

#include <stdio.h>
#include <windows.h>
#include <process.h>
#include <jni.h>

/*
Include jni.h for JNI specific methods. This header file can
be found in the JDK include directory. Include the path to
the JNI include directories in your project make file.
For example:
If you have JDK 1.3.1 installed in C:\ directory, include
the following two directories:

C:\jdk1.3.1\include
C:\jdk1.3.1\include\win32

In addition you must link your executable to the jvm.lib
library and add the path to the jvm.dll to your PATH or
LD_LIBRARY_PATH environment variable to enable the exe
to load the JVM.

Compile a Java class with main (an example java file is
provided:

public class JNIEmbedTest
{
   public static void main(String [] args)
   {
      System.out.println("Hello from JNIEmbedTest");
      System.out.println("String from C: " + args[0]);
   }
}

Place both the executable and the class file in the same
directory and execute the executable with the Java class
file name as the argument.
*/

/* The path where the class file being executed can be found */
#define USER_CLASSPATH "."
#define USER_LIBPATH "."

/*
 The following structure is used to pass data from the
 main thread to worker threads. The usage of this will
 become clear later in the program.
*/
typedef struct threadData
{
   JNIEnv         *env;
   JavaVM         *jvm;
   char         *sClassName;
   int            iThreadIndex;
} tstThreadData;

/**
 * CallMain
 *
 * Calls the main method of a class file.
 * Passes the string "Hello World frm C!" to the Java
 * class as the argument to the main method.
 */
int CallMain(JNIEnv *env, JavaVM *jvm, const char *sClassName)
{
   jclass         cls;
   jmethodID      mid;
   jstring         jstr;
   jobjectArray   args;

   /* locate and load the class file */
    if ((cls = (*env)->FindClass(env, sClassName)) == 0)
   {
        fprintf(stderr, "Can't find class %s\n", sClassName);
        return -1;
    }
 
   /* locate the main method */
    if ((mid = (*env)->GetStaticMethodID(env, cls, "main", "([Ljava/lang/String;)V")) == 0)
   {
        fprintf(stderr, "Can't find main method in class %s\n", sClassName);
        return -1;
    }

   /* create a new java string to be passes to the class */
    if ((jstr = (*env)->NewStringUTF(env, "Hello World from C!")) == 0)
   {
        fprintf(stderr, "Out of memory\n");
        return -1;
    }

   /* create a new string array with a single element containing the
   string created above */
    args = (*env)->NewObjectArray(env, 1, (*env)->FindClass(env, "java/lang/String"), jstr);
    if (args == 0)
   {
        fprintf(stderr, "Out of memory\n");
        return -1;
    }

   /* call the main method with the required arguments */
    (*env)->CallStaticVoidMethod(env, cls, mid, args);

   return 0;
}

/**
 * CallMainInThread
 *
 * Calls the main method of the class file inside a worker
 * thread created in C. This involves attaching the native
 * thread to the JVM and involing the main method in the thread.
 */
int CallMainInThread(JNIEnv *env, JavaVM *jvm, const char *sClassName, int threadNum)
{
   jint res;

   /* attach the current native thread created in C to the JVM */
   /* pass NULL as the third argument */
   res = (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
   if (res < 0)
   {
      fprintf(stderr, "Thread %d: attach failed\n", threadNum);
      return -1;
   }

   printf("Thread %d running\n", threadNum);
   /* call the main method. the method will now be called in the
   context of the C thread, which has now been attached to the JVM */
   CallMain(env, jvm, sClassName);

   /* print out any exceptions that might have occured in Java */
   /* It is extremely important to check, handle, and clear the pending
   exception before calling subsequent JNI functions. Calling arbitrary
   JNI functions with a pending exception may lead to unexpected results.
   You can safely call only a small number of JNI functions when there
   is a pending exception. These functions are ExceptionOccurred,
   ExceptionDescribe, and ExceptionClear.
   */
   if ((*env)->ExceptionOccurred(env))
   {
      (*env)->ExceptionDescribe(env);
      (*env)->ExceptionClear(env);
   }

   /* detach the current thread from the JVM. */
   (*jvm)->DetachCurrentThread(jvm);

   return 0;
}

/**
 * TestThread
 *
 * This method is the entry point for the C thread. The argument it
 * receives is an instance of the structure of type tstThreadData.
 * It extracts the relevant stuff from the structure and calls the
 * method CallMainInThread to actually attach the thread to the JVM
 * and call the Java class.
 */
void TestThread(void *args)
{
   tstThreadData *pThreadData = (tstThreadData *)args;

   CallMainInThread(pThreadData->env, pThreadData->jvm, pThreadData->sClassName, pThreadData->iThreadIndex);

   _endthread();
}

/**
 * The main method.
 * Creates the JVM. Calls the Java class in both threaded and
 * non-threaded manner
 */
int main(int argc, char **argv)
{
   JNIEnv         *env;
   JavaVM         *jvm;
   JavaVMInitArgs    vm_args;
   JavaVMOption   options[4];
   jint         res;
   int            iThreadIndex;
   tstThreadData   *pThreadData;

    /* IMPORTANT: specify vm_args version # if you use JDK1.1.2 and beyond */
    vm_args.version = JNI_VERSION_1_2;
   vm_args.nOptions = 0;

   options[0].optionString = "-Djava.compiler=NONE"; /* disable JIT */
   options[1].optionString = "-Djava.class.path=" USER_CLASSPATH; /* user classes */
   options[2].optionString = "-Djava.library.path=" USER_LIBPATH; /* set native library path */
   options[3].optionString = "-verbose:jni"; /* print JNI-related messages */

   if(1 == argc)
   {
        fprintf(stderr, "Usage: %s <main class name>\n", argv[0]);
        exit(1);
   }

   printf("Running class %s.\n", argv[0]);
   printf("After the program is finished, press ENTER to terminate the JVM.\n");

    /* Create the Java VM */
    if ((res = JNI_CreateJavaVM(&jvm,(void **)&env,&vm_args)) < 0)
   {
        fprintf(stderr, "Can't create Java VM\n");
        exit(1);
    }

   /* call the main method of the Java class from the main thread */
   CallMain(env, jvm, argv[1]);

   /* Create 5 threads and call the Java class from the threads */
   pThreadData = malloc(5 * sizeof(tstThreadData));

    for (iThreadIndex=0; iThreadIndex<5; iThreadIndex++)
   {
      tstThreadData   *pThisThreadData = pThreadData + iThreadIndex;

      pThisThreadData->env = env;
      pThisThreadData->jvm = jvm;
      pThisThreadData->sClassName = argv[1];
      pThisThreadData->iThreadIndex = iThreadIndex;
        /* We pass the thread number as the argument to every thread */
        _beginthread(TestThread, 0, (void *)pThisThreadData);
   }

   getchar();

   free(pThreadData);

   /* destroy the JVM */
    (*jvm)->DestroyJavaVM(jvm);

   return 0;
}




Code:



/* JNIEmbedTest.java
 This is a sample program for use with JNIEmbed.c.
 After compiling JNIEmbed, you can invoke JNIEmbed
 with this class as the parameter.
*/
public class JNIEmbedTest
{
   public static void main(String [] args)
   {
      System.out.println("Hello from JNIEmbedTest");
      System.out.println("String from C: " + args[0]);
   }
}


8207 bytes more | comments? | Printer Friendly Page  Send to a Friend | Score: 0
Posted by Javaaddict on Monday, August 14, 2006 (00:00:00) (11133 reads)

Previous 1060 Stories (530 Pages, 2 Per Page) Next

530| 529| 528| 527| 526| 525| 524| 523| 522| 521| 520| 519| 518| 517| 516| 515| 514| 513| 512| 511| 510| 509| 508| 507| 506| 505| 504| 503| 502| 501| 500| 499| 498| 497| 496| 495| 494| 493| 492| 491| 490| 489| 488| 487| 486| 485| 484| 483| 482| 481| 480| 479| 478| 477| 476| 475| 474| 473| 472| 471| 470| 469|
468
| 467| 466| 465| 464| 463| 462| 461| 460| 459| 458| 457| 456| 455| 454| 453| 452| 451| 450| 449| 448| 447| 446| 445| 444| 443| 442| 441| 440| 439| 438| 437| 436| 435| 434| 433| 432| 431| 430| 429| 428| 427| 426| 425| 424| 423| 422| 421| 420| 419| 418| 417| 416| 415| 414| 413| 412| 411| 410| 409| 408| 407| 406| 405| 404| 403| 402| 401| 400| 399| 398| 397| 396| 395| 394| 393| 392| 391| 390| 389| 388| 387| 386| 385| 384| 383| 382| 381| 380| 379| 378| 377| 376| 375| 374| 373| 372| 371| 370| 369| 368| 367| 366| 365| 364| 363| 362| 361| 360| 359| 358| 357| 356| 355| 354| 353| 352| 351| 350| 349| 348| 347| 346| 345| 344| 343| 342| 341| 340| 339| 338| 337| 336| 335| 334| 333| 332| 331| 330| 329| 328| 327| 326| 325| 324| 323| 322| 321| 320| 319| 318| 317| 316| 315| 314| 313| 312| 311| 310| 309| 308| 307| 306| 305| 304| 303| 302| 301| 300| 299| 298| 297| 296| 295| 294| 293| 292| 291| 290| 289| 288| 287| 286| 285| 284| 283| 282| 281| 280| 279| 278| 277| 276| 275| 274| 273| 272| 271| 270| 269| 268| 267| 266| 265| 264| 263| 262| 261| 260| 259| 258| 257| 256| 255| 254| 253| 252| 251| 250| 249| 248| 247| 246| 245| 244| 243| 242| 241| 240| 239| 238| 237| 236| 235| 234| 233| 232| 231| 230| 229| 228| 227| 226| 225| 224| 223| 222| 221| 220| 219| 218| 217| 216| 215| 214| 213| 212| 211| 210| 209| 208| 207| 206| 205| 204| 203| 202| 201| 200| 199| 198| 197| 196| 195| 194| 193| 192| 191| 190| 189| 188| 187| 186| 185| 184| 183| 182| 181| 180| 179| 178| 177| 176| 175| 174| 173| 172| 171| 170| 169| 168| 167| 166| 165| 164| 163| 162| 161| 160| 159| 158| 157| 156| 155| 154| 153| 152| 151| 150| 149| 148| 147| 146| 145| 144| 143| 142| 141| 140| 139| 138| 137| 136| 135| 134| 133| 132| 131| 130| 129| 128| 127| 126| 125| 124| 123| 122| 121| 120| 119| 118| 117| 116| 115| 114| 113| 112| 111| 110| 109| 108| 107| 106| 105| 104| 103| 102| 101| 100| 99| 98| 97| 96| 95| 94| 93| 92| 91| 90| 89| 88| 87| 86| 85| 84| 83| 82| 81| 80| 79| 78| 77| 76| 75| 74| 73| 72| 71| 70| 69| 68| 67| 66| 65| 64| 63| 62| 61| 60| 59| 58| 57| 56| 55| 54| 53| 52| 51| 50| 49| 48| 47| 46| 45| 44| 43| 42| 41| 40| 39| 38| 37| 36| 35| 34| 33| 32| 31| 30| 29| 28| 27| 26| 25| 24| 23| 22| 21| 20| 19| 18| 17| 16| 15| 14| 13| 12| 11| 10| 9| 8| 7| 6| 5| 4| 3| 2| 1|


Home Code Examples Java Forum All Java Tips Books Submit News, Code... Search... Offshore Software Tech Doodling

RSS feed Java FAQ RSS feed Java FAQ News     

    RSS feed Java Forums RSS feed Java Forums

All logos and trademarks in this site are property of their respective owner. The comments are property of their posters, all the rest 1999-2006 by Java FAQs Daily Tips.

Interactive software released under GNU GPL, Code Credits, Privacy Policy