Wednesday, December 2, 2009

Java Native Interface

Here is an example for Java Native Interface
Java application that calls a C function and executes the operation.
Ping program
           Write a java program for ping operation.
import java.util.StringTokenizer;

public class PINGMain {

String ipaddress = null;

boolean defragment = false;

int num = 2;

String str = "";

String success ="success";

String[] ipaddr = { "", "20", "2000", "5000", "500" };

private String destination;

private String packetSize;

private String bytes;

private String time;

        private String ttl;

protected native String ping(String[] ipaddress);

public PINGMain() {


try {


} catch (UnsatisfiedLinkError e) {





private void singlePing() {

int a = 10;

int b = 20;

String string=null;

while(true) {

string = ping(ipaddr);


StringTokenizer strToken = new StringTokenizer(string);

int numToken = strToken.countTokens();

            destination =   strToken.nextToken();

            bytes = strToken.nextToken();

            time=       strToken.nextToken();

            ttl = strToken.nextToken();

System.out.println("\n Reply from"+" "+destination+" "+"bytes"+" "+bytes+" "+"Time"+" "+time+" "+"TTL"+" "+ttl);



private String continuousPing() {

return null;


private String disconnect() {


//System.out.println("Unloaded SuccessFully");

return success;


private void unLoadPing() {

// unLoad();



* @return


private String getStatistics() {

return null;


public static void main(String ar[]) {

new PINGMain();




Step 2:

   Using javac to compile the PINGMain source file

After you have defined the PINGMain class, save the source code in a file called PINGMain .java. Then compile the source file using the javac compiler as follows:

This command will generate a PINGMain.class file in the current directory.

Step 3:

Using javah -jni to generate a C header file (PINGMain.h) containing the function prototype for the native method implementation

Next we will use the javah tool to generate a JNI-style header file that is useful when implementing the native method in C. You can run javah on the PINGMain class as follows:

  • javah -jni PINGMain

    The command shown above generates a file named PINGMain.h.

  • Step 4:

    Writing the C implementation (PINGMain.c) of the native method

    The JNI-style header file generated by javah helps you to write C or C++ implementations for the native method. The function that you write must follow the -prototype specified in the generated header file.

    #pragma comment(lib, "wsock32.lib")

    #include "jni.h"

    #include "com_dtt_traffic_ping_PINGMain.h"

    #include "stdlib.h"

    #include "StdAfx.h"

    #include <windows.h>

    #include <winsock.h>

    #include <stdio.h>

    #include <string.h>

    int packetsize;

    int count;

    char *data;//Ping info

    typedef struct tagIPINFO


            u_char Ttl;                             // Time To Live

            u_char Tos;                             // Type Of Service

            u_char IPFlags;                 // IP flags

            u_char OptSize;                 // Size of options data

            u_char FAR *Options;    // Options data buffer


    typedef struct tagICMPECHO


            u_long Source;                  // Source address

            u_long Status;                  // IP status

            u_long RTTime;                  // Round trip time in milliseconds

            u_short DataSize;               // Reply data size

            u_short Reserved;               // Unknown

            void FAR *pData;                // Reply data buffer

            IPINFO  ipInfo;                 // Reply options


    // ICMP.DLL Export Function Pointers

    HANDLE (WINAPI *pIcmpCreateFile)(VOID);

    BOOL (WINAPI *pIcmpCloseHandle)(HANDLE);

    DWORD (WINAPI *pIcmpSendEcho)




    char *pingFun(char *dest[])


        int timeout;

        char ping_Resp[2048];

            WSADATA wsaData;                        // WSADATA

            ICMPECHO icmpEcho;                      // ICMP Echo reply buffer

            HANDLE hndlIcmp;                        // LoadLibrary() handle to ICMP.DLL

            HANDLE hndlFile;                        // Handle for IcmpCreateFile()

            LPHOSTENT pHost;                    // Pointer to host entry structure

            struct in_addr iaDest;              // Internet address structure

            DWORD *dwAddress;                       // IP Address

            IPINFO ipInfo;                          // IP Options structure

            int nRet;                                       // General use return code

            DWORD dwRet;                            // DWORD return code

            int x;

           packetsize = atoi(dest[2]);

            count = atoi(dest[5]);

            timeout = atoi(dest[4]);

            // Dynamically load the ICMP.DLL

            hndlIcmp = LoadLibrary("ICMP.DLL");

            if (hndlIcmp == NULL)


                    fprintf(stderr,"nCould not load ICMP.DLLn");



            // Retrieve ICMP function pointers

            pIcmpCreateFile = (HANDLE (WINAPI *)(void))


            pIcmpCloseHandle = (BOOL (WINAPI *)(HANDLE))


            pIcmpSendEcho = (DWORD (WINAPI *)



            // Check all the function pointers

            if (pIcmpCreateFile == NULL             ||

                    pIcmpCloseHandle == NULL        ||

                    pIcmpSendEcho == NULL)


                    fprintf(stderr,"nError getting ICMP proc addressn");




            // Init WinSock

            nRet = WSAStartup(0x0101, &wsaData );

        if (nRet)


            fprintf(stderr,"nWSAStartup() error: %dn", nRet);





        // Check WinSock version

        if (0x0101 != wsaData.wVersion)


            fprintf(stderr,"nWinSock version 1.1 not supportedn");





            // Lookup destination

        // Use inet_addr() to determine if we're dealing with a name

        // or an address

        iaDest.s_addr = inet_addr(dest[1]);

        if (iaDest.s_addr == INADDR_NONE)

            pHost = gethostbyname(dest[1]);


            pHost = gethostbyaddr((const char *)&iaDest,

                            sizeof(struct in_addr), AF_INET);

            if (pHost == NULL)


                    fprintf(stderr, "n%s not foundn", dest[1]);





            // Tell the user what we're doing

            /*printf("nPinging %s [%s]", pHost->h_name,


            // Copy the IP address

            dwAddress = (DWORD *)(*pHost->h_addr_list);

            // Get an ICMP echo request handle

            hndlFile = pIcmpCreateFile();

           // for (x = 0; x < 4; x++)

                    // Set some reasonable default values

                    ipInfo.Ttl =dest[3];

                    ipInfo.Tos = 0;

                    ipInfo.IPFlags = 0;

                    ipInfo.OptSize = 0;

                    ipInfo.Options = NULL;

                    //icmpEcho.ipInfo.Ttl = 256;

                    // Reqest an ICMP echo

                    dwRet = pIcmpSendEcho(

                            hndlFile,               // Handle from IcmpCreateFile()

                            *dwAddress,             // Destination IP address

                            packetsize,                   // Pointer to buffer to send

                            0,                              // Size of buffer in bytes

                            &ipInfo,                // Request options

                            &icmpEcho,              // Reply buffer

                            sizeof(struct tagICMPECHO),

                            timeout);                  // Time to wait in milliseconds

                    // Print the results

                    iaDest.s_addr = icmpEcho.Source;

                   /* printf("\n Reply from %s  Time=%ldms  TTL=%d",




                    sprintf(ping_Resp,"%s %d %ld %d",    




                    if (icmpEcho.Status)


                           // printf("nError: icmpEcho.Status=%ld",

                            //        icmpEcho.Status);

                            printf("\n Request timed out");




            // Close the echo request file handle




            return ping_Resp;


    JNIEXPORT jstring JNICALL Java_com_dtt_traffic_ping_PINGMain_ping

       (JNIEnv *env, jclass job, jobjectArray oarr)


       jsize argc = (*env)->GetArrayLength(env, oarr);

       /* Declare a char array for argv */

       int i;

       char const* argv[128];

       for (i = 1; i < 6; i++)


          /* obtain the current object from the object array */

          jobject myObject = (*env)->GetObjectArrayElement(env, oarr, i-1);

          /* Convert the object just obtained into a String */

          const char *str = (*env)->GetStringUTFChars(env,myObject,0);

          /* Build the argv array */

          argv[i] = str;


         data=(char *)malloc(sizeof(char) * 2048);


        // printf("Data %s ",data);

          return ((*env)->NewStringUTF(env,data));



            Compiling the C implementation into a native library, creating ping.dll or

    On Solaris or Linux, the following command builds a shared library called

    cc -G -I/java/include -I/java/include/solaris

    PINGMain.c -o

    On Win32, the following command builds a dynamic link library (DLL) ping.dll using the Microsoft Visual C++ compiler:

  • cl -Ic:\java\include -Ic:\java\include\win32

    -MD -LD PINGMain.c -ping.dll

    Step 6: Running the

    java PINGMain

        If you get the following error put the dll file in the java path

    java.lang.UnsatisfiedLinkError: no PINGMain in library path

    at java.lang.Runtime.loadLibrary(

    at java.lang.System.loadLibrary(

    at PINGMain .main(


    Post a Comment

    The Link Exchange - Your ultimate resource for link exchange!

    About This Blog

      © Blogger template Webnolia by 2009

    Back to TOP