Quick Search for:  in language:    
HTML,intro,Java,Native,Interface,using,which,
   Code/Articles » |  Newest/Best » |  Community » |  Jobs » |  Other » |  Goto » | 
CategoriesSearch Newest CodeCoding ContestCode of the DayAsk A ProJobsUpload
Java/ Javascript Stats

 Code: 220,465. lines
 Jobs: 89. postings

 How to support the site

 
Sponsored by:

 
You are in:
 

Does your code think in ink?
Login





Latest Code Ticker for Java/ Javascript.
Gobang
By Geniusbob Xu Qiang on 11/27


Click here to see a screenshot of this code!Salary
By Vikram Ivatury on 11/25

(Screen Shot)

Click here to see a screenshot of this code!A (part10) Powerful Swing Code to Maintain CD Database
By James Smith K on 11/25

(Screen Shot)

String Calculator
By MadokaCoder on 11/24


Chobi Dekha
By ShuvoRim on 11/23


Click here to see a screenshot of this code!A basic Client Server application II
By Ronald Holland on 11/23

(Screen Shot)

Bookmark image
By darren kurn on 11/22


myFT
By Owolabi Oyapero on 11/22


Click here to see a screenshot of this code!Simple Socket example
By Steven McElrea on 11/20

(Screen Shot)

Click here to put this ticker on your site!


Add this ticker to your desktop!


Daily Code Email
To join the 'Code of the Day' Mailing List click here!

Affiliate Sites



 
 
   

Java Native Interface by Example

Print
Email
 

Submitted on: 7/22/2002 2:09:59 PM
By: Ali Ezad Abbas  
Level: Advanced
User Rating: By 18 Users
Compatibility:Java (JDK 1.1), Java (JDK 1.2)

Users have accessed this article 5355 times.
 
(About the author)
 
     Its an intro to the Java Native Interface using which you can incorporate native (C/C++ or even Assembly) code into your java programs.(Now in HTML format!!)

 
 
Terms of Agreement:   
By using this article, you agree to the following terms...   
1) You may use this article in your own programs (and may compile it into a program and distribute it in compiled format for languages that allow it) freely and with no charge.   
2) You MAY NOT redistribute this article (for example to a web site) without written permission from the original author. Failure to do so is a violation of copyright laws.   
3) You may link to this article from another website, but ONLY if it is not wrapped in a frame. 
4) You will abide by any additional copyright restrictions which the author may have placed in the article or article's description.
Java Native Interface <--[if gte mso 9]> Ali Ezad Abbas Normal Ali Ezad Abbas 2 123 2002-07-23T17:15:00Z 2002-07-23T17:15:00Z 2 1442 8224 Macrosoft inc. 68 16 10099 9.2720

Java Native Interface

 

Java is a powerful object oriented programming language. The real power of Java lies in its portability. Java programs created on one platform can be run equally well on another platform as long as a Java Virtual Machine (JVM) implementation is available for that perticular platform. Java API (Application Programming Interface) is another of Java’s strong points. The Java API provides most of the functionality that a developer needs, however, there are situations where the API can’t cater to the programmer’s needs. Java designers foresaw this problem and provided an elegant workaround for such situations. The solution they proposed was the Java Native Interface, commonly known as JNI.

 

JNI is sort of a bridge between the Java programming language and the native environment for which the JVM is implemented. Simply stated, you can incorporate native code (written in C/C++ or even assembly language) into your Java programs thus enhancing the capabilities of Java. The question arises here, why do we need to incorporate native code in Java programs at all?? Well, there are lots of reasons for this! For example, in Java you can’t reference memory locations directly as you can do in C or C++ (with pointers). Pointers are to the programming community, what “friction” is to the mechanical engineers. You hate to have it, but you can’t do without it!! It is impossible to write drivers for various hardware interfaces without performing direct memory references. For example, the printer port of a PC is usually mapped to the memory location 378 (hexadecimal). If you want to do anything with your printer port you need to reference the memory location 0x378!! Similarly, character display memory in a PC is mapped to the memory starting at 0xB80 (0xB00 for monochrome displays).

 

Referencing memory is not the only situation where Java fails to provide support. There can be hundreds of other situations where a Java programmer would be stuck if he didn’t have JNI at his disposal. The standard Java API, for example, doesn’t provide any password input stream for console applications (where you type in something and only asterisks ‘*’ are echoed to the console).

 

Writing native methods for the Java Program involves the following steps:

  1. Create a Java class that declares the native method; this class contains the declaration or signature for the native method.
  2. Compile the Java class that declares the native method.
  3. Generate a header file for the native method using the “javah” program provided with the Java SDK.
  4. Write the implementation of the native method in the programming language of your choice, such as C, C++ or even assembly language.
  5. Compile the header and implementation files into a shared library file (dll in case of the windows platform).
  6. Run the Java program.

 

 

 

Lets follow these steps and create a simple program to demonstrate the usage of Java Native Interface. The program we will create will provide us with a Password Input Stream to read private information from the console.

STEP 1: Write the Java Program:

The Java program in this case is quite simple. It defines two methods. It defines a native method readChar() and implements a method readLine() that in turn calls the native method. The program is listed below:

public class PasswordInputStream {

   static {

      System.loadLibrary("password");

   }

   public String readLine () {

      String s = "";

      int input = readChar();

      while (input!=13) {

         s = s + (char)input;

         input = readChar();

      }

      System.out.println();

      return s;

   }

   public native int readChar ();

}

 

The “loadLibrary” method in the System class loads the Dynamically Linked Library (dll) associated with this program. We’ll talk about these in a moment. The static construct will be new to a lot of people. Well just think of it as a substitution to the main method. Since there is no main method in this simple program (we wish to use it as a utility class), so we’re using the “static” construct.

 

The readLine() method reads chararacters from the console using the native method readChar() and concatenates them into a string (by the way, 13 is the ascii code for the return key in decimal).

 

The last line of the program provides the signature of the readChar method. The keyword “native” indicates that the method will be implemented in a native language and is thus not implemented in the program.

 

STEP 2: Compile the program:

 

Now that you’ve created the program, you need to compile it in the usual manner. Use the “javac” compiler to compile it.

 

STEP 3: Generate a header file:

 

The next step is to generate a header file for the native language. Header files can be thought of as interfaces with respect to Java. These provide the native method prototypes and define various macros and variables for the JNI. Our header file provides the C language signature for the readChar() method.

 

You can write your own header file, but you’ll need to be familiar with C/C++ to do that. JDK solves this problem with the “javah” program. It automatically generates a header file for you. Run it by using the command “javah PasswordInputStream” and it will create the file “PasswordInputStream.h”. The file is listed below:

 

/* DO NOT EDIT THIS FILE - it is machine generated */

#include

/* Header for class PasswordInputStream */

 

#ifndef _Included_PasswordInputStream

#define _Included_PasswordInputStream

#ifdef __cplusplus

extern "C" {

#endif

/*

 * Class:     PasswordInputStream

 * Method:    readChar

 * Signature: ()I

 */

JNIEXPORT jint JNICALL Java_PasswordInputStream_readChar

  (JNIEnv *, jobject);

 

#ifdef __cplusplus

}

#endif

#endif

 

You don’t need to know too much about this file. Contrast the Java method declaration:

 

   public native int readChar ();

 

with the native signature:

 

JNIEXPORT jint JNICALL Java_PasswordInputStream_readChar     (JNIEnv *, jobject);

 

You can see that the “int” data type is mapped to the “jint” data type in the native signature. The name of the native language function that implements the native method consists of the prefix Java_, the package name, the class name, and the name of the native method. Between each name component is an underscore "_" separator.

Notice that the implementation of the native function, as it appears in the header file, accepts two parameters even though, in its definition on the Java side, it accepts no parameters. The JNI requires every native method to have these two parameters.

STEP 4: Write the native implementation:

We are now ready to implement the readChar() method in the native language (C in this case). The choice of the native language is solely a choice of the developer, however, the language must have a compiler, linker with the ability to create shared libraries (DLLs in case of windows platform).

The C code is given below:

#include conio.h

#include stdio.h

#include jni.h

#include "PasswordInputStream.h"

JNIEXPORT jint JNICALL Java_PasswordInputStream_readChar (JNIEnv *env, jobject obj) {

   int a = getch();

   if (a!=13) {

      printf("*");  

   }

   return a;

}

For those of you not too familiar with C I’ll briefly describe what this code means. The lines starting with the pound sign (#) are pre-processor directives. The “include” directive simply inserts the named file into the current file. You can do that by using a word processor and not use the “include” directive at all!! We’re including the conio.h file because it contains the prototype (signature) of the C library function, “getch()”. Similarly, stdio.h contains the prototype for the “printf()” C library function.

Jni.h provides information that the native language code requires to interact with the Java runtime system. When writing native methods, you must always include this file in your native language source files.

The method simply reads a character from the console and if its not the carriage-return (ascii code 13 decimal) then prints an asterisk to the console.

 

STEP 5: Compile the native program:

Now that you have implemented the method in the native language, you need to compile it into a shared library. You’ll need a C compiler that can create shared libraries. I personally use Borland’s C++ Builder. Microsoft’s Visual C/C++ compiler also has the capability to compile as a shared library. Microsoft’s Quick C compiler I heard could compile to shared libraries but it has poor documentation and online help and I couldn’t find the switch for the purpose!! If you want to deploy the shared library to some platform other than Microsoft windows, then you need to create a shared library for that platform. You can create a shared library on a Unix/Linux variant by using the “gcc” compiler.

You need to put “\include” and “\include\win32” in the “include” path of your compiler in the windows environment.

The compiler will generate a .dll file. You need to place this dll file in the directory where you java program is located or put it in the “\bin” for global access.

STEP 6: Test/Run the program:

Finally you need to test the program that you created. Lets create a simple test program to see if everything works as expected. The test program is listed below:

public class test {

   public static void main (String [] args) {

      PasswordInputStream pis = new PasswordInputStream();

      System.out.print("Password: ");

      String passwd = pis.readLine();

      System.out.println("You entered: "+passwd);

   }

}

 

It creates an instance of the PasswordInputStream class and then uses the readLine instance method to read a password. It then displays the password to the user (not a smart move!!).

 

The discussion was meant to be an introduction to JNI. There is definitely more to it and you can learn more by going through the various articles and tutorials at http://java.sun.com.

If you read this article please vote for it. It'll take less than a minute of your time!!

 


Other 19 submission(s) by this author

 

 
Report Bad Submission
Use this form to notify us if this entry should be deleted (i.e contains no code, is a virus, etc.).
Reason:
 
Your Vote!

What do you think of this article(in the Advanced category)?
(The article with your highest vote will win this month's coding contest!)
Excellent  Good  Average  Below Average  Poor See Voting Log
 
Other User Comments
7/23/2002 10:41:06 AM:Jose M Serrano
excellent stuff, but may you write it in HTML Format, please ??
Keep the Planet clean! If this comment was disrespectful, please report it:
Reason:

 
7/23/2002 12:36:45 PM:Jose M Serrano
ok, thanks Ali, it's looks better. 5 applets from me
Keep the Planet clean! If this comment was disrespectful, please report it:
Reason:

 
7/29/2002 12:55:26 PM:M Sain
Hi, Excellent stuff. Never knew java could do this...thanx for sharing!!!
Keep the Planet clean! If this comment was disrespectful, please report it:
Reason:

 
7/29/2002 3:01:17 PM:Adeel
Excellent stuff!I was unsure of the capability Java had.It certainly offers alot to the programmers.
Keep the Planet clean! If this comment was disrespectful, please report it:
Reason:

 
10/8/2002 1:07:48 AM:Sing Dome
Neat! I read Sun's java reference several times before but never figured out how those pieces are put together. Thanks for the article. By the way, how do you generate a dll in UNIX? gcc doesn't seem to be fond of jni.h and jni_md.h copied directly from win32 platforms. Any suggestions?
Keep the Planet clean! If this comment was disrespectful, please report it:
Reason:

 
10/8/2002 1:55:43 AM:Ali Ezad Abbas
you'll have to use the header files from the linux version of java sdk available for free at http://java.sun.com
Keep the Planet clean! If this comment was disrespectful, please report it:
Reason:

 
Add Your Feedback!
Note:Not only will your feedback be posted, but an email will be sent to the code's author in your name.

NOTICE: The author of this article has been kind enough to share it with you.  If you have a criticism, please state it politely or it will be deleted.

For feedback not related to this particular article, please click here.
 
Name:
Comment:

 

Categories | Articles and Tutorials | Advanced Search | Recommended Reading | Upload | Newest Code | Code of the Month | Code of the Day | All Time Hall of Fame | Coding Contest | Search for a job | Post a Job | Ask a Pro Discussion Forum | Live Chat | Feedback | Customize | Java/ Javascript Home | Site Home | Other Sites | About the Site | Feedback | Link to the Site | Awards | Advertising | Privacy

Copyright© 1997 by Exhedra Solutions, Inc. All Rights Reserved.  By using this site you agree to its Terms and Conditions.  Planet Source Code (tm) and the phrase "Dream It. Code It" (tm) are trademarks of Exhedra Solutions, Inc.