Writing native methods in java

Java Tip 23: Write native methods

The ability to write just one set of code in Java and have it run on every system with a Java run-time is one of Java’s primary strengths. But this platform independence has one key drawback: What do we do with the vast amount of existing code? The trick is to use the so-called native method interface.

Writing native methods involves importing C code into your Java application. In this tip I’ll walk you through the basic recipe for creating native methods and using them in a Java application.

Seven steps to native method nirvana The steps to creating native methods are as follows:

  • Write Java code
  • Compile Java code
  • Create C header (.h file)
  • Create C stubs file
  • Write C code
  • Create shared code library (or DLL)
  • Run application

Our exercise is to write some text to the console from inside the native method. The specifics of this example will be geared toward a Unix-like system, specifically Linux. I’ll point out the couple of spots where the details differ for other platforms.

Читайте также:  Unique page title - My Site

Write Java code

Write your Java code as you normally would. To use native methods in your Java code, you must do two things. First, write a native method declaration for each native method that you want to use. This is just like writing the declaration of a normal Java method interface, but you must specify the native keyword, as follows:

public native void printText ();

The second hoop to jump through is you must explicitly load the native code library. (We will create this later.) We do this by loading the library in a class static block:

To put these pieces together for our example, create a file called Happy.java with the following contents:

class Happy < public native void printText (); static < System.loadLibrary ("happy"); /* Note lowercase of classname! */ >public static void main (String[] args) < Happy happy = new Happy (); happy.printText (); >>

Compile Java code

Compile the Happy.java file:

Create a C header file

There are various magic incantations that must be made available so that our C code can be used as a native method. The javah functionality of the Java compiler will generate the necessary declarations and such from our Happy class. This will create a Happy.h file for us to include in our C code:

Create a C stubs file

In a manner reminiscent of the mangling that C++ translators do to the names of C++ methods, the Java compiler has a similar madness. To ease the pain of having to write a lot of tedious code so that our C code can be invoked from the Java run-time system, the Java compiler can generate the necessary trampoline code automatically for us:

Write C code

Now, let’s write the actual code to print out our greeting. By convention we put this code in a file named after our Java class with the string «Imp» appended to it. This results in HappyImp.c . Place the following into HappyImp.c :

#include &ltStubPreamble.h> /* Standard native method stuff. */ #include «Happy.h» /* Generated earlier. */ #include &ltstdio.h> /* Standard C IO stuff. */ void Happy_printText (struct HHappy *this)

In interfacing your C code with Java, many other aspects are involved — such as how to pass and return the myriad types. For more information, see the Java tutorial or the Hermetica Native Methods Paper (see the Resources section for URLs).

Create a shared library

This section is the most system-dependent. It seems like every platform and each compiler/linker combination has a different method of creating and using shared libraries. For folks using any of the various Microsoft Windows platforms, check the documentation for your C compiler for the nitty-gritty details.

For you Linux folks, here’s how to create a shared library using GCC. First, compile the C source files that we have already created. You have to tell the compiler where to find the Java native method support files, but the main trick here is that you have to explicitly tell the compiler to produce Position Independent Code:

% gcc -I/usr/local/java/include -I/usr/local/java/include/genunix -fPIC -c Happy.c HappyImp.c

Now, create a shared library out of the resulting object (.o) files with the following magical incantation:

% gcc -shared -Wl,-soname,libhappy.so.1 -o libhappy.so.1.0 Happy.o HappyImp.o

Copy the shared library file to the standard short name:

% cp libhappy.so.1.0 libhappy.so

Finally, you may need to tell your dynamic linker where to find this new shared library file. Using the bash shell:

% export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH

Execute the application

Run the Java application as usual:

Well, that’s all there is to it. Thanks to Tony Dering for passing on the Linux-specific incantations.

A quick design note

Before rushing off to write native methods for all of that legacy code, I would caution all of us to look carefully at the existing systems and see if there are better ways to connect them to Java. For instance, there are Java Database Connectivity (JDBC) and even higher-level solutions for accessing databases from Java. So, look at all of the tricks in your bag and use what makes sense for the project at hand.

This story, «Java Tip 23: Write native methods» was originally published by JavaWorld .

Next read this:

Copyright © 1997 IDG Communications, Inc.

Источник

Write Native Methods in Java

Write Native Methods in Java

  1. What Are Native Methods in Java
  2. Write Native Methods in Java Programs

This article takes you through various steps necessary to learn how to write native methods in Java programs.

What Are Native Methods in Java

The native keyword is a modifier in Java programming, used with methods only. It represents that this particular method is written in the native code via Java Native Interface (JNI).

The native (or foreign) methods are implemented in C, C++, or any other platform-dependent code.

[public/protected/private] native [returnType] youMethodName(); 

Write Native Methods in Java Programs

Listed below is the multi-step process to write native methods in Java programs:

Write the Java program containing the native method’s declaration and the main method to call the native method.
Compile the Java program with the main method and declare the specified native method.
Use javah with -jni flag to create the header file for the native method.
Write the code for the native method in the programming language you like, for instance, C/C++.
Create the shared library to compile the implementation and header files.
Finally, execute/run the Java Program.

Let’s follow all of these steps to call native methods in the Java program.

Write a Java Program

class nativeDemoClass  //declaration of the native method  public native void showMessage();   //load native C library  static  System.loadLibrary("nativedemoclass"); //lowercase of classname  >   //java main method  public static void main (String[] args)  nativeDemoClass demo = new nativeDemoClass();  demo.showMessage();  > > 

We must include the native keyword as a method’s declaration part in the Java program if we implement the method in a programming language other than Java.

This native keyword tells the Java compiler that this specific method is a native programming language method. Remember, the declaration of a native method in the Java program provides the method signature only.

We have a static block that loads the native C library in which we have written the implementation of the showMessage() method. Have you noticed that we are passing a string to the System.loadLibrary() method?

Why is it so? It is because this static block from the nativeDemoClass class will load the appropriate library, named nativedemoclass .

Let’s move to the second step and compile the Java program.

Compile the Java Program

Use the command given below to compile the Java program.

javac nativeDemoClass.java 

After successfully compiling the Java program, we get the nativeDemoClass.class file.

Create a Header File

Use the following command to create a header file.

Here, -h produces the C/C++ header files and places the generated file into the specified directory. We use dot ( . ) to keep the generated header file in the current directory.

javac -h . nativeDemoClass.java 

You may find on the Internet that javah creates C/C++ header files, which was correct until JDK 8. According to the oracle, javah is deprecated now, but we have an alternative solution given above.

The nativeDemoClass.h file looks as follows. We do not edit this because it is a machine-generated file.

/* DO NOT EDIT THIS FILE - it is machine generated */ #include  /* Header for class nativeDemoClass */  #ifndef _Included_nativeDemoClass #define _Included_nativeDemoClass #ifdef __cplusplus  extern "C"  #endif  /* * Class: nativeDemoClass * Method: showMessage * Signature: ()V */ JNIEXPORT void JNICALL Java_nativeDemoClass_showMessage  (JNIEnv *, jobject);  #ifdef __cplusplus  > #endif #endif 

The JNIEXPORT void JNICALL Java_nativeDemoClass_showMessage declares the C function in this header file. We can have multiple function signatures if the nativeDemoClass has more native methods.

  • Prefix as Java_
  • The package name
  • The class name
  • native method’s name

Each section is separated by an underscore ( _ ), as shown graphically below:

Write Native Methods in Java - Naming Convention

Further, the JNIEnv* refers to the Java Native Interface environment that allows us to access the Java Native Interface (JNI) methods. The jobject references this object of Java programming.

Write the Native Code

#include #include "nativeDemoClass.h" #include  JNIEXPORT void JNICALL Java_nativeDemoClass_showMessage(JNIEnv *env, jobject obj)   printf("Hello world!\n");  return; > 

The implementation of Java_nativeDemoClass_showMessage is pretty straightforward because we are only using a printf() statement to print Hello world . Remember, this .c file has three headers, jni.h , stdio.h , and nativeDemoClass.h created in the previous step.

Create the Shared Library

Use the following command to create the shared library. We must have build tools for visual studio to use the CL command.

cl -Ic:\java\jdk-17.0.2\include -Ic:\java\jdk-17.0.2\include\win32 -LD nativeDemoClassImp.c -Fenativedemoclass.dll 

Remember, the Java program uses the following method to load the shared library, named nativedemoclass at run time.

System.loadLibrary("nativedemoclass"); 

Run the Java Program

Finally, use the command given below to run the Java program.

You will see Hello world! on the command line if you have done everything correctly.

Write Native Methods in Java - Output

Mehvish Ashiq is a former Java Programmer and a Data Science enthusiast who leverages her expertise to help others to learn and grow by creating interesting, useful, and reader-friendly content in Computer Programming, Data Science, and Technology.

Related Article — Java Method

Источник

Оцените статью