| <html> | |
| <head> | |
| <title>Beginning JNI with NetBeans IDE and C/C++ Plugin on Linux</title> | |
| <meta name="DESCRIPTION" content="A tutorial describing how to compile | |
| and run JNI powered Java applications using NetBeans IDE or Oracle Solaris Studio IDE."> | |
| <meta name="author" content="Susan Morgan"><!--Optional tag--> | |
| <link rel="stylesheet" type="text/css" href="../../../netbeans.css"> | |
| <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" > | |
| </head> | |
| <body> | |
| <a name="top"></a> | |
| <h1>Beginning JNI with NetBeans IDE and C/C++ Plugin on Linux</h1> | |
| <!-- START INTRO ---------------------------------------------------------------------------------------* --> | |
| <div class="articledate" style="margin-left: 0px;font-style:italic;"> | |
| <!-- <p><em>Contributed by <i>Susan Morgan</i> <br> --> | |
| <em>March 2014</em> [Revision number: V8.0-1]</div> | |
| <p>This tutorial takes you through the creation of a simple application that | |
| uses Java<sup><small>TM</small></sup> Native Interface (JNI) code written in the C | |
| programming language. | |
| <p class="notes">The tutorial is specific to Linux.</p> | |
| <!-- END INTRO --> | |
| <h3>Contents</h3> | |
| <img src="../../../images_www/articles/74/netbeans-stamp-80-74.png" class="stamp" | |
| alt="Content on this page applies to NetBeans IDE 7.4and 8.0" title="Content on this page applies to the NetBeans IDE 7.4 and 8.0"> | |
| <table class="b-none vatop" cellpadding="0" cellspacing="0"> | |
| <tr> | |
| <td class="hyphen">- </td> | |
| <td><a href="#requirements" title="Requirements">Requirements</a></td> | |
| </tr> | |
| <tr> | |
| <td class="hyphen">- </td> | |
| <td><a href="#modules" title="Setting Up Your Environment for the Tutorial"> | |
| Setting Up Your Environment for the Tutorial</a></td> | |
| </tr> | |
| <tr> | |
| <td class="hyphen">- </td> | |
| <td><a href="#javaproject" title="Setting Up the Java Application | |
| Project">Setting Up the Java Application Project</a></td> | |
| </tr> | |
| <tr> | |
| <td class="hyphen">- </td> | |
| <td><a href="#c-library" title="Setting Up a New C/C++ Dynamic Library Project"> | |
| Setting Up a New C/C++ Dynamic Library Project</a> | |
| </td> | |
| </tr> | |
| <tr> | |
| <td class="hyphen">- </td> | |
| <td><a href="#running" title="Building and Running the | |
| Application">Building and Running the Application | |
| </a></td> | |
| </tr> | |
| <tr> | |
| <td class="hyphen">- </td> | |
| <td><a href="#next" title="Next Steps">Next Steps | |
| </a></td> | |
| </tr> | |
| </table> | |
| <h2><A NAME="requirements"></a>Requirements</h2> | |
| <p><b>To follow this tutorial, you need the following software and resources.</b> </p> | |
| <table> | |
| <tbody> | |
| <tr> | |
| <th class="tblheader" scope="col">Software or Resource</th> | |
| <th class="tblheader" scope="col">Version Required</th> | |
| </tr> | |
| <tr> | |
| <td class="tbltd1">NetBeans IDE</td> | |
| <td class="tbltd1"><a | |
| href="https://netbeans.org/downloads/index.html">version 7.4 or 8.0 with NetBeans C/C++ plugin</a></td> | |
| </tr> | |
| <tr> | |
| <td class="tbltd1">Java Developer Kit (JDK)</td> | |
| <td class="tbltd1"><a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html">version 7 or 8</a></td> | |
| </tr> | |
| <tr> | |
| <td class="tbltd1"> | |
| C and C++ compilers, <tt>make</tt>, <tt>gdb</tt></td> | |
| <td class="tbltd1"> | |
| <a HREF="../../../community/releases/80/cpp-setup-instructions.html"> | |
| Configuring the NetBeans IDE for C/C++/Fortran</a></td> | |
| </tr> | |
| </table> | |
| <p>See the <a href="../../../community/releases/80/install.html">NetBeans IDE | |
| 8.0 Installation | |
| Instructions</a> and <a | |
| HREF="../../../community/releases/80/cpp-setup-instructions.html"> | |
| Configuring the NetBeans IDE for C/C++/Fortran</a> for | |
| information on downloading and installing the required software. | |
| </p> | |
| <h2><a name="modules"></a>Setting Up Your Environment for the Tutorial</h2> | |
| <p>You need both Java modules and C/C++ | |
| modules for this tutorial. If you already have downloaded the NetBeans IDE C/C++ bundle, | |
| you can download the additional Java modules separately.</p> | |
| <p>To determine if you have the Java and C/C++ modules, select File > New Project. | |
| The project categories should include both Java and C/C++. | |
| <p><b>To download Java and C/C++ modules that may be missing:</b></p> | |
| <ol><li>In the NetBeans IDE, select Tools > Plugins.</li> | |
| <li>In the Available Plugins tab, select the checkbox for Java or C/C++, depending | |
| on which is missing from your IDE. If you already have the plugins, they | |
| will be listed in the Installed tab. | |
| </li> | |
| <li>Click Install.</li> | |
| <li>Click Next in the NetBeans IDE Installer dialog box, accept the license terms checkbox, | |
| and click Install.</li> | |
| <li>Click Finish when the installation is complete.</li></ol> | |
| <h2><a name="javaproject"></a>Setting Up the Java Application Project</h2> | |
| <p> | |
| This program requires a Java project and a C project. In this section, | |
| you will create and configure the Java project for 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. | |
| </p> | |
| <ol> | |
| <li>Choose File > New Project. Select the Java category and Java Application | |
| project type. Click Next.<br> | |
| <img src="../../../images_www/articles/74/cnd/beginning-jni-linux/jni-new-project-java.png" alt="Screenshot | |
| of the New Project Wizard" class="margin-around"></li> | |
| <li>In the Project Name field, type <tt>JNIDemoJava</tt>.</li> | |
| <li>You can change the Project Location to any directory on your computer, but here | |
| we use the default NetBeansProjects in the user directory. | |
| </li> | |
| <li>Leave the Create Main Class checkbox selected and change the Main class name to | |
| <tt>jnidemojava.Main</tt>.<br> | |
| <br> | |
| <img src="../../../images_www/articles/74/cnd/beginning-jni-linux/jni-new-java-app.png" alt="Screenshot | |
| of the Name and Location page of the New Java Application Wizard" class="margin-around"> | |
| </li> | |
| <li>Click Finish. <br> <br> | |
| <p> | |
| The IDE creates the <tt>NetBeansProjects/JNIDemoJava</tt> project folder. | |
| </p> | |
| </li> | |
| </ol> | |
| <h3>Editing the Main Class Source</h3> | |
| <ol> | |
| <li>To open the Main class source in the editor, right-click the <tt>Main.java</tt> class | |
| node and choose Open.</li> | |
| <li>Replace the line <tt>//TODO code application logic here</tt> in the <tt>main</tt> method with the following: | |
| <pre class="examplecode">new Main().nativePrint();</pre> | |
| </li> | |
| <li>Notice the indicator in the left margin showing an error and lightbulb. Click on the indicator, | |
| and you are prompted with a shortcut to create the method <tt>nativePrint</tt>. </li> | |
| <li>Click on this shortcut and the IDE inserts the following code: | |
| <pre class="examplecode">private void nativePrint() { | |
| throw new UnsupportedOperationException("Not supported yet"); | |
| }</pre> | |
| </li> | |
| <li>Delete the line | |
| <pre class="examplecode">throw new UnsupportedOperationException("Not supported yet");</pre> | |
| </li> | |
| <li>Modify the <tt>nativePrint()</tt> method by | |
| inserting the <tt>native</tt> keyword into the method signature so that | |
| it now looks as follows: | |
| <pre class="examplecode">private native void nativePrint();</pre> | |
| <p> | |
| The <tt>native</tt> keyword indicates that the method has an implementation located in | |
| an external native library. However, at runtime the library location is not clear. | |
| </p> | |
| <p>The new main method should look as follows:</p> | |
| <pre class="examplecode">public static void main(String[] args) { | |
| new Main().nativePrint(); | |
| } | |
| private native void nativePrint(); | |
| }</pre> | |
| </li> | |
| <li>Right-click the project name and select Clean and Build. The project should build | |
| successfully. | |
| </li> | |
| </ol> | |
| <h3><a name="header"></a>Creating the Native Library Header File</h3> | |
| In this section we use <tt>javah</tt>, a Java tool that creates a C header from a Java class. | |
| <ol> | |
| <li>In a terminal window, navigate to the <tt>NetBeansProjects</tt> | |
| directory. | |
| </li> | |
| <li>Type the following: | |
| <pre class="examplecode"> | |
| javah -o JNIDemoJava.h -classpath JNIDemoJava/build/classes jnidemojava.Main | |
| </pre> | |
| <p> | |
| A <tt>JNIDemoJava.h</tt> C header file is generated in the NetBeansProjects directory. | |
| This file is required to provide a correct function declaration for the native implementation of the | |
| <tt>nativePrint()</tt> method. You will need it later when you create the C part of this application.</p> | |
| </li> | |
| <li>Switch back to the NetBeans IDE window. | |
| </li> | |
| </ol> | |
| <p><b>Summary</b> | |
| <p>In this exercise you created a new 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, you created a C | |
| header file, which is required later for the native library compilation.</p> | |
| <h2><a name="c-library"></a>Setting Up a New C/C++ Dynamic Library Project</h2> | |
| <p>This section shows you how to create the native part | |
| of the application. You will create the C++ Dynamic Library project and | |
| configure it to be able to build JNI code. | |
| </p> | |
| <p>After you have set up the project, you will create the implementation for | |
| the native method you declared earlier in the Java part of the application. | |
| <ol> | |
| <li> | |
| Choose File > New Project. Under Categories, select C/C++. Under | |
| Projects, select C/C++ Dynamic Library. Click Next. | |
| <br> | |
| <img src="../../../images_www/articles/74/cnd/beginning-jni-linux/jni-new-project-c.png" | |
| alt="Screenshot of the Choose Project page of the New Project wizard" class="margin-around"> | |
| </li> | |
| <li>In the Project Name field, type <tt>JNIDemoCdl</tt>. | |
| </li> | |
| <li>In the Project Location field, use the same location that you used for | |
| the Java application project, <tt>NetBeansProjects</tt>. The | |
| location should be shown as the default value. | |
| </li> | |
| <li>Accept the defaults for all other fields and click Finish. | |
| <p>The IDE creates the <tt>NetBeansProjects/JNIDemoCdl</tt> project | |
| folder. | |
| </p> | |
| </li> | |
| </ol> | |
| <h3>Setting Project Properties</h3> | |
| <ol> | |
| <li>Right-click the JNIDemoCdl project node and choose Properties.</li> | |
| <li>In the Properties dialog box, select the C Compiler node under the Build properties.</li> | |
| <li>Click the Include Directories and Headers ... button and click Add in the Include Directories and Headers dialog box. | |
| <li>Browse into your JDK directory, and select the <tt>include</tt> subdirectory. </li> | |
| <li>Select the Store path as Absolute option, then click Select to add this directory to the project's | |
| Include Directories.</li> | |
| <li>Add the JDK's <tt>include/linux</tt> directory in the same way, then click OK. | |
| <br> | |
| <img src="../../../images_www/articles/74/cnd/beginning-jni-linux/jni-include-directories.png" alt="Screenshot of the Project Properties dialog | |
| box and the Debug-Include Directories dialog box" class="margin-around"> | |
| <p>These settings are required to enable references to the Java <tt>jni.h</tt> library | |
| from your C code. | |
| </p> | |
| </li> | |
| <li> | |
| Find the Compilation Line area of the C Compiler options. Click in the text field of the Additional Options | |
| property and type <tt>-shared -m32</tt>. | |
| <img src="../../../images_www/articles/74/cnd/beginning-jni-linux/jni-project-properties-cmd-options.png" | |
| alt="Screenshot of the Debug-Additional Optionstext field being edited" class="margin-around"> | |
| <p> | |
| The <tt>-shared</tt> option tells the compiler to generate a dynamic library.<br> | |
| The | |
| <tt>-m32</tt> option tells the compiler to create a 32-bit binary. By default on 64-bit | |
| systems the compiled binaries are 64-bit, which causes a lot of problems with | |
| 32-bit JDKs. | |
| </p> | |
| </li> | |
| <li> | |
| Click the Linker category in the left panel.</li> | |
| <li>Click the Output text field, and replace the string | |
| <pre class="examplecode">${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/libJNIDemoCdl.so</pre> | |
| with the string | |
| <pre class="examplecode">dist/libJNIDemoCdl.so</pre> | |
| to simplify the path of the resulting shared object file. | |
| This will make the file easer to reference from Java.<br> | |
| <img src="../../../images_www/articles/74/cnd/beginning-jni-linux/jni-project-properties-linker.png" | |
| alt="Screenshot of the Project Properties dialog box with Linker properties" class="margin-around"> | |
| </li> | |
| <li>Click OK. The defined settings are saved. | |
| </li> | |
| </ol> | |
| <h3>Adding a Header File</h3> | |
| <ol> | |
| <li>Go to a terminal window and move the <tt>JNIDemoJava.h</tt> header file that | |
| you generated previously from your <tt>NetBeansProjects</tt> directory to the | |
| C/C++ Library project directory, <tt>NetBeansProjects/JNIDemoCdl</tt>. | |
| </li> | |
| <li> | |
| <p>In the Projects window, right-click the Header Files node | |
| of the <tt>JNIDemoCdl</tt> project and choose Add Existing Item. Navigate to | |
| the <tt>NetBeansProjects/JNIDemoCdl</tt> directory and select the <tt>JNIDemoJava.h</tt> file, then click | |
| Select. | |
| </p> | |
| <p>The <tt>JNIDemoJava.h</tt> file appears under Header Files. | |
| </p> | |
| <img src="../../../images_www/articles/74/cnd/beginning-jni-linux/jni-source-files-include-file.png" alt="Screenshor of | |
| the Projects window" class="margin-around b-all"> | |
| </li> | |
| </ol> | |
| <h3>Implementing a Method</h3> | |
| <ol> | |
| <li>Right-click the Source Files node of the <tt>JNIDemoCdl</tt> project and choose New > C Source File. Type | |
| <tt>JNIDemo</tt> in the File Name field, and click Finish. The editor opens | |
| the <tt>JNIDemo.c</tt> file. | |
| </li> | |
| <li>Edit the <tt>JNIDemo.c</tt> file by typing the following code: | |
| <pre class="examplecode"> | |
| #include <jni.h> | |
| #include <stdio.h> | |
| #include "JNIDemoJava.h" | |
| JNIEXPORT void JNICALL Java_jnidemojava_Main_nativePrint | |
| (JNIEnv *env, jobject obj) | |
| { | |
| printf("\nHello World from C\n"); | |
| } | |
| </pre> | |
| </li> | |
| <li>Save the <tt>JNIDemo.c</tt> file.</li> | |
| <li> | |
| Right-click the <tt>JNIDemoCdl</tt> project node and choose Build. The | |
| Output window displays <tt>BUILD SUCCESSFUL (total time 171ms)</tt> or similar. | |
| </li> | |
| </ol> | |
| <p><b>Summary</b></p> | |
| <p>In this exercise you created a new C/C++ Dynamic Library, specified its | |
| location, and configured it to be able to build a JNI implementation of your | |
| Java method. You added the generated header file for the native method you | |
| declared in the Java application, and implemented it. | |
| </p> | |
| <h2><a name="running"></a>Building and Running the Application</h2> | |
| <p> | |
| In this exercise, you will perform some final alterations to the Java part of | |
| the application. These changes are required to ensure the Java part properly | |
| loads the native library you compiled in the previous exercise. After that you | |
| will compile and run the resulting application. | |
| </p> | |
| <div class="indent"> | |
| <h3>Configuring the Java Project</h3> | |
| <ol> | |
| <li>Open the <tt>Main.java</tt> file in the editor. | |
| <li>Add the following initialization code for the C++ dynamic library after the <tt>public class Main</tt> line, using the path to the output file | |
| that you shortened | |
| in the previous exercise: | |
| <pre class="examplecode"> | |
| static { | |
| System.load("<i>full-path-to-NetBeansProjects-dir</i>/JNIDemoCdl/dist/libJNIDemoCdl.so"); | |
| } | |
| </pre> | |
| Replace <i>full-path-to-NetBeansProjects-dir</i> with the path to your NetBeansProjects directory, | |
| which should be something similar to | |
| <tt>/home/<i>username</i>/NetBeansProjects</tt> | |
| </li> | |
| <li>Save the <tt>Main.java</tt> file.</li> | |
| </ol> | |
| <h3>Running the JNIDemoJava Application</h3> | |
| <ol><li>Select the JNIDemoJava application in the Projects window.</li> | |
| <li>Press F6 or click the Run button in the toolbar to run the application. | |
| The program should execute correctly and the Output window should display output similar to the following: | |
| <br> | |
| <img src="../../../images_www/articles/72/cnd/beginning-jni-linux/jni-build-success.png" | |
| alt="Screenshot of the Output window" class="margin-around"> | |
| </li> | |
| </ol> | |
| <h3>Summary</h3> | |
| <p>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. | |
| </p> | |
| </div> | |
| <h2><a name="next"></a>Next Steps</h2> | |
| <p>If you want to check your work against a working example, you can | |
| <a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FCPlusPlus%252FJNIDemo.zip" target="_blank"> | |
| download a zip file containing the source code</a> from netbeans.org. | |
| </p> | |
| <p> | |
| You can use the following documents to get more information: | |
| <ul> | |
| <li><a href="quickstart.html"> | |
| C/C++ Projects Quick Start Tutorial</a> | |
| <li><a href="http://docs.oracle.com/javase/7/docs/technotes/guides/jni/" target="_blank">JNI Specification</a></li> | |
| <li><a href="http://en.wikipedia.org/wiki/Java_Native_Interface" target="_blank">Java Native Interface</a> | |
| </ul> | |
| <DIV CLASS="feedback-box"> | |
| <A | |
| HREF="https://netbeans.org/about/contact_form.html?to=7&subject=Feedback:%20Beginning%20JNI%20with%20NetBeans%20IDE%20and%20C/C++%20Plugin%20on%20Linux">Send Feedback on This Tutorial</a> | |
| </DIV> | |
| </body> | |
| </html> |