Beginning JNI with NetBeans™ C/C++ Pack 5.5, Part I
Contributed and maintained by
and
.
The tutorial will guide you through the creation of a sample
application which uses JNI to execute some native code written in
the C programming language. For the Java™ part of the application you
will use NetBeans™ IDE 5.5; for the C part - NetBeans™ C/C++ Pack
5.5.
You will start off by creating a simple Java project, adding a native
method to it and then implementing this method in C using
NetBeans C/C++ Pack 5.5.
This is the first part of the tutorial that covers the creation of a sample
JNI application in the Microsoft® Windows®
operating system.
Expected duration: 30 minutes
Prerequisites
This tutorial assumes you have some basic knowledge of, or
programming experience with, the following technologies:
Exercise 0: Installing and Configuring Tutorial Environment
This exercise will guide you through the process of installing and
configuring the required software. While the installation of JDK,
NetBeans IDE and NetBeans C/C++ Pack is pretty trivial, Cygwin
requires special attention.
After you install the software, some minor changes to the system
configuration should be applied.
At the Choose Installation Type page, select Install From
Internet, and click Next.
At the Choose Installation Directory page, define the
settings appropriate for your system, then click Next.
At the Select Local Package Directory page, define the directory
which Cygwin installer will use as its cache directory, and
click Next.
At the Select Connection Type page, choose the type of
Internet connection you have, and click Next.
At the Choose Download Site(s) page, select a mirror which is
closest to your location, and click Next.
At the Select Packages page, select at least these
packages: gcc-core, gcc-g++, gdb, and
make. You can select other packages as well but
these are required for the tutorial.
Figure 1
Figure 2
Figure 3
Click Next. The Cygwin installer proceeds with
the download and configuration of the selected packages.
Configuring System
Add the <CYGWIN_HOME>\bin directory path
to the PATH environment variable value.
Running the Software
Start the NetBeans IDE.
Setting Up General Java Application Project
The goal of this exercise is to create and configure the Java part
of the JNI application you will be developing. You will create a
new Java application project, initialize its main class and add a
native method to this class.
Creating General Java Application Project
Choose File > New Project. Under Categories, select
General. Under Projects, select Java Application, and
click Next.
Figure 4
Under Project Name, enter HelloWorld.
Change the Project Location to any directory on your
computer (hereinafter, this directory is referred to as
<PROJECTS_ROOT>).
Leave the Create Main Class checkbox selected and accept
the default value for the corresponding text field.
Figure 5
Leave the Set as Main Project checkbox selected, and click
Finish.
The IDE creates the
<PROJECTS_ROOT>/HelloWorld project
folder.
Editing Main Class Source
To open the Main class source in the editor, right-click the Main class node, and choose Open from the context menu.
Replace the body
of the main method with
the following:
new Main().nativePrint();
Wait till the newly entered line gets underlined with a red
wave. Press Alt - Enter and choose the Create method
nativePrint() in helloworld.Main line from the drop-down list.
A compilation error was caused by referencing a non-existing method in Step 2 above and the IDE automatically proposes a
fix for this problem.
Figure 6
Edit the nativePrint() method. Delete the contents
of the method and add the native keyword to the
method signature. So the method now should look like this:
private native void nativePrint();
The native keyword indicates that the method
has an implementation located in an external native
library, thus the code is going to compile correctly. However at runtime the library location is not clear. Refer to the Configuring the Java Project section below for details.
Press Ctrl - F11 to clean and build the project.
The project should build successfully.
Creating Native Library Header File
Switch to the console and navigate to the
<PROJECTS_ROOT> directory.
A HelloWorldNative.h C header file is
generated. It is required to provide correct function
declaration for the native implementation of the
nativePrint() method.
Switch back to the NetBeans IDE window.
Summary
In this exercise you created a new General Java Application
Project, specified its location and defined the package and
name of the main class of the project. You also added a new
method to the main class and marked it as a method having a
native implementation. As a final step we created a C header
file which is required later for the native library compilation.
Setting Up New C/C++ Dynamic Library Project
This exercise will lead you through the creation of the
native part of the sample application. You will create the C++
Dynamic Library project and configure it to be able to build the JNI
code.
After the project has been set up, you will create the
implementation for the native method, you have declared earlier in
the Java part of the application.
Creating New C/C++ Dynamic Library Project
Choose File > New Project. Under Categories, select
C/C++ Development. Under Projects, select C/C++ Dynamic
Library, and click Next.
Figure 7
Under Project Name, type HelloWorldNative.
Under Project Location, type the same location as you
entered for the General Java Application project,
<PROJECTS_ROOT>. The required value should
be already there as the default value.
Accept the defaults for all other fields.
Figure 8
Leave the Set as Main Project checkbox selected.
Then click Finish.
The IDE creates the
<PROJECTS_ROOT>/HelloWorldNative
project folder.
Setting Project Properties
Right-click the project node and choose Properties
from the context menu.
In the opened dialog box navigate to Configuration
Properties > C/C++ > GNU C Compiler > General.
Edit the values of the Additional Include Libraries
properties. Set them to <JAVA_HOME>/include,
<JAVA_HOME>/include/win32.
These settings are required to enable references to the
Java jni.h library from your C code. Note: If <JAVA_HOME> contains
spaces, please ensure you embedded the path into quotation
marks, otherwise you may experience build
problems.
Figure 9
Navigate to Configuration Properties > C/C++ > GNU C
Compiler > Command Line. Edit the value of the
Additional Options property. Set it to -mno-cygwin
-Wl,--add-stdcall-alias -shared -m32.
The -mno-cygwin option, enables building
DLLs that have no dependencies on Cygwin own libraries
and thus can be executed on machines which do not have
Cygwin installed.
The -Wl,--add-stdcall-alias passes the
--add-stdcall-alias option to the linker;
without it, the resulting application would fail with
the UnsatisfiedLinkError.
The -shared option tells the compiler to
generate a DLL ( not an executable file). -m32 tells the compiler to create a 32-bit
binary. On 64-bit systems the compiled
binaries are 64-bit by default , which causes a lot of problems
with 32-bit JDKs.
Figure 10
Navigate to Configuration Properties > Linker >
General. Edit the value of the Output property. Set it to
dist/HelloWorldNative.dll.
The goal of this step is to simplify the
path of the resulting DLL file, in order to make referencing it from Java easier for
you.
Figure 11
Click OK.
The defined settings are saved.
Adding Header File
Copy the generated <PROJECTS_ROOT>\HelloWorldNative.h header file to the
C/C++ Library project directory,
<PROJECTS_ROOT>\HelloWorldNative.
In the Projects view, navigate to HelloWorldNative >
Source Files. Right-click the Source Files node and
choose Add Existing Item from the context menu. Point the
IDE to the HelloWorldNative.h file.
The HelloWorldNative.h file appears
under Source Files.
Implementing Method
Right-click the Source Files node and choose New > Add
Empty C File from the context menu. Under File Name type
HelloWorldNative, and click Finish.
The editor opens the HelloWorldNative.c file.
Figure 12
Edit the HelloWorldNative.c file by typing the
following code:
#include <jni.h>
#include <stdio.h>
#include "HelloWorldNative.h"
JNIEXPORT void JNICALL Java_helloworld_Main_nativePrint
(JNIEnv *env, jobject obj)
{
printf("\nHello World from C\n");
}
Figure 13
Right-click the HelloWorldNative project node
and choose Build Project.
The Output dialog box displays Build successful.
Exit value 0.
Figure 14
Summary
In this exercise you created a new C/C++ Dynamic Library,
specified its location and configured it to be able to build
JNI implementation of your Java method. You added the generated
header file for the native method you have declared in the Java
application and implemented it.
Building and Running Application
In this exercise you will perform some final alterations to the Java
part of the application. This is required to ensure the Java part properly loads the native
library you had compiled in the previous exercise. After that you
will compile and run the resulting application.
To set the HelloWorld Java project as the main
project, right-click the project node and
choose Set As Main Project from the context menu.
Press F6 to run the application.
The program should execute correctly and the
Output dialog box should say:
Hello World from C
BUILD SUCCESSFUL (total time: 0 seconds)
Figure 16
Summary
In this exercise you made some final configuration steps and
ran the application to verify that the implementation of the
native method comes from the native C library.
Next Steps
You can download the sources for this tutorial from
here.
You can use the following documents to get more information: