{"id":138,"date":"2014-12-11T19:07:41","date_gmt":"2014-12-11T19:07:41","guid":{"rendered":"http:\/\/www.baruchyoussin.com\/?p=138"},"modified":"2015-02-04T09:12:39","modified_gmt":"2015-02-04T09:12:39","slug":"java-native-interface-jni-programmer-guide-tutorial-javah","status":"publish","type":"post","link":"https:\/\/baruchyoussin.com\/en\/java-native-interface-jni-programmer-guide-tutorial-javah.html","title":{"rendered":"Step by step Java Native Interface (JNI) guide and tutorial | JNI programmer&#8217;s guide | javah tutorial"},"content":{"rendered":"<br \/>\n<h2><span id=\"what_are_jni_and_this_guide\">What are JNI and this guide<\/span><\/h2>\n<p>Java Native Interface (JNI) is a simple tool that allows calling \t\tnative functions from Java code. In addition, a native function which \t\tis called by Java may be able to call back Java functions but we shall \t\tnot discuss this functionality in this tutorial.<\/p>\n<p>There are plenty of existing guides (some of them are listed \t\tbelow), and I am not competing with them.<\/p>\n<p>Rather, my purpose is to complement them with my experiences: \t\twhen I tried to use JNI myself and followed these tutorials, I found a \t\tfew difficulties which were not covered in them, and I wanted explain \t\thow I dealt with these difficulties which included packages and \t\tmangling conventions. This step-by-step guide explains exactly how I \t\tdealt with the difficulties I encountered.<\/p>\n<h2><span id=\"my_environment\">My environment<\/span><\/h2>\n<p>I have been writing code that was supposed to work on Windows \t\twhile running myself a Linux Ubuntu with Eclipse Java development \t\tenvironment.<\/p>\n<p>Of course, I needed a Windows machine to compile and run Windows \t\tcode, and for this purpose I had access to a Windows XP 32-bit \t\tcomputer on which I ran Eclipse 4.3.2, both for Java and for C\/C++ \t\tnative code; for C\/C++ I used MinGW C\/C++ toolchain.<\/p>\n<p>Note that the dll I produced on the 32 bit computer, cannot be \t\tcalled from 64-bit code. Practically, this means that if I run 32-bit \t\tJRE, whether on 32-bit computer or an AMD64 one, I can call this dll \t\tfrom it; however, if I run 64-bit JRE (this can be done only on an \t\tAMD64 computer), I cannot call this library.<\/p>\n<p>A side note: if you need to cover both 32-bit and 64-bit JRE, \t\tyou need to compile two different dlls, write Java code that \t\tdetermines whether your JRE is 32-bit or 64-bit, and load the \t\tappropriate one of the two, e.g.:<\/p>\n<pre><code>if(Platform.osArch.contains(\"64\")) {<br><em>   load your 64-bit dll<\/em><br>}<br>else {<br><em>   load your 32-bit dll<\/em><br>}<\/code><\/pre>\n<h2><span id=\"first_read_the_existing_tutorials\">First, read the existing tutorials<\/span><\/h2>\n<p> \t\tI suggest starting with reading a <a \t\t\thref=\"http:\/\/www2.sys-con.com\/itsg\/virtualcd\/Java\/archives\/0203\/seshadri\/index.html\"> \t\t\tnice introduction and a step-by-step guide written in 2004 by Govind \t\t\tSeshadri<\/a>. We shall follow the same steps below, although I shall add \t\tsome details of mine. If you want, you can complement it with the <a \t\t\thref=\"http:\/\/en.wikipedia.org\/wiki\/Java_Native_Interface\"> \t\t\tWikipedia article<\/a>. \t<\/p>\n<p> \t\tOther resources: there is a faster and more advanced <a \t\t\thref=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/java\/JavaNativeInterface.html\"> \t\t\ttutorial<\/a> and a <a \t\t\thref=\"http:\/\/www.javaworld.com\/article\/2076513\/java-concurrency\/enhance-your-java-application-with-java-native-interface--jni-.html \t\"> \t\t\tJavaWorld article by Tal Liron<\/a>. \t<\/p>\n<h2><span id=\"how_to_run_javah_to_create_a_c_header_for_jni_functions\">How to run javah to create a C header for JNI functions<\/span><\/h2>\n<p>This is the first step in implementing JNI.<\/p>\n<p>Create a java file with a native function declaration (as \t\texplained in the above tutorials), and compile it.<\/p>\n<p>Open a terminal.<\/p>\n<p> \t\tIf your java files were created by Eclipse, go to the \t\t<code>bin\/<\/code> \t\tdirectory of the project (i.e., \t\t<code>cd<\/code> \t\tto this directory). \t<\/p>\n<p> \t\tOtherwise, go to the directory where the package tree of the class \t\tfiles starts (the \t\t<code>bin\/<\/code> \t\tdirectory of an Eclipse project is a particular case of it). \t<\/p>\n<p> \t\tE.g., if \t\t<code>MyClass<\/code> \t\tis declared in the package \t\t<code>Pkg1.Pkg2.Pkg3<\/code> \t\tand \t\t<code>MyClass.class<\/code> \t\tlies in \t\t<code>MyDir\/Pkg1\/Pkg2\/Pkg3<\/code> \t\tthen \t\t<code>cd<\/code> \t\tin your terminal to \t\t<code>MyDir<\/code> \t\t. \t<\/p>\n<p> \t\tAfter that run javah:<br \/> \t\t<code>javah Pkg1.Pkg2.Pkg3.MyClass<\/code> \t<\/p>\n<p> \t\tThis creates your header file:<br \/> \t\t<code> Pkg1_Pkg2_Pkg3_MyClass.h<\/code> \t<\/p>\n<p> \t\tIt is placed in the same directory, \t\t<code>MyDir<\/code> \t\t. \t<\/p>\n<p>This file contains the C\/C++ declarations of the native \t\tfunctions to be called from Java. It starts with the lines<\/p>\n<pre><code>\/* DO NOT EDIT THIS FILE - it is machine generated *\/<br>#include &lt;jni.h&gt;<\/code><\/pre>\n<p> \t\tThe header file referenced here, \t\t<code>jni.h<\/code> \t\t, is provided by java; I have found it in the directory \t<\/p>\n<pre><code>&lt;Java installation directory&gt;\/jdk1.7.0_51\/include<\/code><\/pre>\n<p>On my Windows computer, this is<\/p>\n<pre><code>C:\\Program Files\\Java\\jdk1.7.0_51\\include<\/code><\/pre>\n<p>This directory needs to be added to the include path, together \t\twith its subdirectory win32<\/p>\n<pre><code>&lt;Java installation directory&gt;\/jdk1.7.0_51\/include\/win32<\/code><\/pre>\n<p> \t\tthat contains another header file, \t\t<code>jni_md.h<\/code> \t\twhich is \t\t<code>#include<\/code> \t\t&#8216;d by \t\t<code>jni.h<\/code> \t\t. \t<\/p>\n<p> \t\t<small> (Note that <code>jdk1.7.0_51<\/code> in the directory \t\t\tpath reflects the fact that I was running jdk 1.7.0 Release 51; if \t\t\tyou update your jdk to a later version, while doing that you change \t\t\tthe directory name <code>jdk1.7.0_51<\/code> accordingly and want to \t\t\tbuild your dll again, you would have to update your include path.) \t\t<\/small> \t<\/p>\n<p> \t\tStill, Eclipse with MinGW C\/C++ compliler could not find this include \t\teven though it could display \t\t<code>jni.h<\/code> \t\tin its include list. The only thing that helped, was to replace the \t\tline<br \/> \t\t<code> #include &lt;jni.h&gt;<\/code> \t\t<br \/> by<br \/> \t\t<code> #include \"jni.h\"<\/code> \t\t<br \/> (Regretfully, I had to disregard the warning not to edit \t\tthis file.) \t<\/p>\n<p>After that the file successfully compiled.<\/p>\n<h2><span id=\"calling_this_code_from_java\">Calling this code from java<\/span><\/h2>\n<p>The next step is to create a .c file that implements the \t\tdeclarations in this header (assuming you want to implement it in C as \t\tI did).<\/p>\n<p>Compile it to create a Windows dll; if its name is hello.dll \t\tthen do the following.<\/p>\n<p>Place hello.dll on the Java build path of this project; in \t\tEclipse, open Project Properties (by right-clicking on the project in \t\tthe project explorer) \u2192 Java build path \u2192 Source \u2192 native library \t\tlocation \u2192 Edit, and make sure that the folder containing hello.dll is \t\tincluded.<\/p>\n<p>Insert the following code in the class that calls the native \t\tfunction:<\/p>\n<pre><code>static {<br>   System.loadLibrary(\"hello\"); \/\/ Load native library at runtime<br>     \/\/ hello.dll (Windows) or libhello.so (Unixes)<br>}<\/code><\/pre>\n<p> \t\tNote that this code must appear before you actually call your native \t\tfunction; usually this code is put in the same java class in which you \t\thave declared your native function in java. For an example, see the <a \t\t\thref=\"http:\/\/en.wikipedia.org\/wiki\/Java_Native_Interface\">Wikipedia \t\t\tarticle referenced above<\/a>. \t<\/p>\n<p> \t\tIf you want your program to deal with the case the library cannot be \t\tloaded, embed the \t\t<code>System.loadLibrary<\/code> \t\tcall in a \t\t<code>try\/catch<\/code> \t\tblock. (The alternative approach that I followed, was to package the \t\tdll together with the Java class files and deal with all problems \t\trelated to this packaging \u2013 including with the possibility that the \t\tnative library cannot be loaded \u2013 manually during debugging.) \t<\/p>\n<h2><span id=\"jni_unsatisfied_link_error\">JNI unsatisfied link error<\/span><\/h2>\n<p> \t\tStill, as I tried to run my program, I got a exception of the type \t\t<code>java.lang.UnsatisfiedLinkError<\/code> \t\t. \t<\/p>\n<p>It was thrown on the line on which I called my native function; \t\tJava could not find it.<\/p>\n<p> \t\tI found some <a \t\t\thref=\"http:\/\/www.velocityreviews.com\/forums\/t143642-jni-unsatisfied-link-error-but-the-method-name-is-correct.html\">good \t\t\tadvice on the net<\/a>; I followed it and installed dumpbin on my Windows \t\tcomputer, see <a href=\"download-dumpbin-microsoft.html\">here<\/a> for \t\tdetails. (The alternative approach is to use <a \t\t\thref=\"http:\/\/sourceforge.net\/projects\/mingw\/files\/MinGW\/Extension\/pexports\/\"> \t\t\tpexports utility of MinGW<\/a>.) \t<\/p>\n<p> \t\tI ran<br \/> \t\t<code> dumpbin \/exports MyDLLname.dll<\/code> \t\t<br \/> (according to the description of dumbin) and found that \t\t<code>@8<\/code> \t\twas added to the name of my exported function, which prevented it from \t\tbeing found. \t<\/p>\n<p> \t\tAs I studied it further, I found out the following.<br \/> The C\/C++ \t\theader file that was created by javah (see above), defined my function \t\twith \t\t<code>JNICALL<\/code> \t\t(see an example in the <a \t\t\thref=\"http:\/\/en.wikipedia.org\/wiki\/Java_Native_Interface\">Wikipedia \t\t\tarticle<\/a>). As I looked for the definition of \t\t<code>JNICALL<\/code> \t\t, I found it in the header file \t\t<code>jni_md.h<\/code> \t\twhich is \t\t<code>include<\/code> \t\t&#8216;d in the header file \t\t<code>jni.h<\/code> \t\t(both mentioned above). The header \t\t<code>jni_md.h<\/code> \t\tdefines \t\t<code>JNICALL<\/code> \t\tas \t\t<code>__stdcall<\/code> \t\t. This is a <a href=\" http:\/\/en.wikipedia.org\/wiki\/Calling_convention\">calling \t\t\tconvention<\/a> and according to <a \t\t\thref=\"http:\/\/msdn.microsoft.com\/en-us\/library\/zxk0tw93%28v=vs.120%29.aspx\"> \t\t\tMicrosoft documentation<\/a> \t\t<code> __stdcall<\/code> \t\tprefixes an underscore _ to the name and suffixes it with @ followed \t\tby the decimal number of bytes in the argument list. \t<\/p>\n<p> \t\tSo the conclusion is that \t\t<code>@8<\/code> \t\tis correct (8 being the number of bytes in the two arguments) but the \t\tleading underscore was missing. \t<\/p>\n<p> \t\tI have found a <a \t\t\thref=\"http:\/\/stackoverflow.com\/questions\/11420153\/java-lang-unsatisfiedlinkerror-returned-when-calling-native-method\"> \t\t\tsolution<\/a> to add the underscore _ before \t\t<code>Java_...<\/code> \t\tin the name of the C function that implements the native Java call. \t\tThis needs to be done in the header file which was generated by javah, \t\tPkg1_Pkg2_Pkg3_MyClass.h \u2013 see above \u2013 and in the .c file that \t\timplements this function. \t<\/p>\n<p>This solution worked successfully.<\/p>\n<p>The remaining question is, whether MinGW compiler operates \t\tlegitimately or not; this question is not entirely academic since if \t\tthis is a bug of MinGW then some next version of MinGW may be expected \t\tto fix it, and at this point the workaround I implemented, would break \t\tdown.<\/p>\n<p> \t\tThe <a href=\"http:\/\/en.wikipedia.org\/wiki\/Name_mangling\"> \t\t\tWikipedia article on Name mangling<\/a> says: \u201cThe mangling scheme was \t\testablished by Microsoft, and has been informally followed by other \t\tcompilers including Digital Mars, Borland, and GNU GCC, when compiling \t\tcode for the Windows platforms.\u201d This means that, on one hand, we \t\tcannot complain to MinGW that this is a bug in the technical sense, \t\tbut we can expect MinGW to fix it eventually. \t<\/p>\n<p> \t\t<small>&copy;Baruch Youssin 2014<\/small> \t<\/p>\n","protected":false},"excerpt":{"rendered":"<p>What are JNI and this guide Java Native Interface (JNI) is a simple tool that allows calling native functions from Java code. In addition, a native function which is called by Java may be able to call back Java functions but we shall not discuss this functionality in this tutorial. There are plenty of existing [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/baruchyoussin.com\/en\/wp-json\/wp\/v2\/posts\/138"}],"collection":[{"href":"https:\/\/baruchyoussin.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/baruchyoussin.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/baruchyoussin.com\/en\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/baruchyoussin.com\/en\/wp-json\/wp\/v2\/comments?post=138"}],"version-history":[{"count":4,"href":"https:\/\/baruchyoussin.com\/en\/wp-json\/wp\/v2\/posts\/138\/revisions"}],"predecessor-version":[{"id":301,"href":"https:\/\/baruchyoussin.com\/en\/wp-json\/wp\/v2\/posts\/138\/revisions\/301"}],"wp:attachment":[{"href":"https:\/\/baruchyoussin.com\/en\/wp-json\/wp\/v2\/media?parent=138"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/baruchyoussin.com\/en\/wp-json\/wp\/v2\/categories?post=138"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/baruchyoussin.com\/en\/wp-json\/wp\/v2\/tags?post=138"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}