Some Notes‎ > ‎

Eclipse: Hello World in Java Native Interface on Windows

15 January 2012

  1. Rationale

To use a single workspace within a single installation of Eclipse to develop a project  which consists of source files written in both C and Java with calls between them – on a Windows x86 based development machine. The rationale being to increase the ease of development and automate certain parts of the build processes.

  1. Software Components used

  • Cygwin OR MinGW for compiling C code
  • JDK for compiling Java code
  • Eclipse as the IDE
  • JDT and CDT plugins for Eclipse
  1. Installation Instructions

Make sure you have the following installed. If not, then follow this particular order
  1. Install Java Development Kit (JDK) Standard Edition (SE) for Windows 32bit
    http://www.oracle.com/technetwork/java/javase/downloads/index.html
  2. Install Eclipse IDE for Java Developers for Windows 32bit
    (This includes JDT)
    http://www.eclipse.org/downloads/
  3. Eclipse Eclipse CDT (C/C++ Development Tooling) Plugin
    http://eclipse.org/cdt/downloads.php
  4. Install EITHER Cygwin
    (During Installation, select the “Devel” option in the Select Packages Window)
    http://www.cygwin.com/install.html
    OR MinGW
    http://www.mingw.org/
    BUT NOT BOTH

  1. Java Code

  1. Start Eclipse. Preferably create a new workspace called WorkSpaceEclipseJNI
  2. From the menu select File>New>Java Project
  3. Enter Project Name as 01Java_HelloWorld
  4. Click Next >
  5. Click Finish
  6. In the Package Explorer expand 01Java_HelloWorld
  7. Right click src folder and select New>Package
  8. Enter Name as com.lithiumhead.jni
  9. Click Finish
  10. In the Package Explorer under 01Java_HelloWorld > src right click com.lithiumhead.jni and select New>Class
  11. Enter Name as HelloWorld
  12. Click Finish
  13. Paste the following code into HelloWorld.java

package com.lithiumhead.jni;

class HelloWorld {
public native void sayHello();

static {
System.loadLibrary("HelloWorld");
}

public static void main(String[] args) {
HelloWorld h = new HelloWorld();
h.sayHello();
}
}
  1. From the menu select Run>External Tools>External Tools Configurations…
  2. Highlight Program in the list in the left pane
  3. Press the New button
  4. Enter Name as javah - C Header and Stub File Generator
  5. For the Location browse to locate javah.exe in the JDK installation folder
    (will be something like
    C:\Program Files\Java\jdk1.7.0\bin\javah.exe)
  6. Enter Working Directory as: ${project_loc}/bin/
  7. Enter Arguments as -jni ${java_type_name}
  8. Click Apply
  9. Switch to the Common tab
  10. Select the checkbox next to External Tools under Display in favourites menu
  11. Click Apply
  12. Click Close
  13. Deselect Build Automatically from Project Menu
  14. In the Package Explorer right click 01Java_HelloWorld and select Build Project
  15. In the Package Explorer highlight HelloWorld.java
  16. From the menu select Run>External Tools>1 javah - C Header and Stub File Generator
    (This will generate the header file for the C code com_lithiumhead_jni_HelloWorld.h placed in the bin folder of 01Java_HelloWorld Java Project.)
  1. C Code

  1. From the menu select File>New>Project…
  2. Expand C/C++
  3. Highlight C Project
  4. Click Next >
  5. Under Project type, expand Shared Library
  6. Highlight Empty Project
  7. Under Toolchains select Cygwin GCC (or MinGW GCC)
  8. Enter Project name as 01C_HelloWorld
  9. Press Next >
  10. Uncheck Debug. Let only Release remain checked.
  11. Click Finish
  12. If asked for switching Perspective to C/C++, check Remember my decision and click Yes
  13. In the Project Explorer right click 01C_HelloWorld and select New>Source File
  14. Enter Source file as com_lithiumhead_jni_HelloWorld.c
  15. Click Finish
  16. Paste the following code in com_lithiumhead_jni_HelloWorld.c

#include <jni.h>

#include "..\01Java_HelloWorld\bin\com_lithiumhead_jni_HelloWorld.h"

#include <stdio.h>

JNIEXPORT void JNICALL Java_com_lithiumhead_jni_HelloWorld_sayHello(JNIEnv *env, jobject obj)

{

printf("Hello world!\n");

return;

}

  1. Press Ctrl+S to save the C code
  2. In the Project Explorer highlight 01C_HelloWorld
  3. Press Alt+Enter to open the Properties for the project
  4. Expand C/C++ Build
  5. Highlight Settings
  6. Highlight Includes from the list within the Tool Settings tab on the right side
  7. Click Add…
  8. Click File System…
  9. Browse to the include folder in the JDK installation folder and click OK
    (must be something like
    C:\Program Files\Java\jdk1.7.0\include)
  10. Click OK
  11. Click Add… again
  12. Click File System… again
  13. Browse to the include\win32 folder in the JDK installation folder and click OK
    (must be something like
    C:\Program Files\Java\jdk1.7.0\include\win32)
  14. Click OK
  15. Highlight Miscellaneous under Cygwin C Linker (or MinGW C Linker) from the list
  16. On the right side, enter Linker flags as -mno-cygwin -Wl,--add-stdcall-alias
    (or just -Wl,--add-stdcall-alias in case of MinGW)
  17. Click Apply
  18. Switch to the Build Artifact tab
  19. Delete the text for Artifact name and type in HelloWorld
  20. Delete the text for Output prefix and keep it empty
  21. Click OK
  22. Right click 01C_HelloWorld in Project Explorer and select Build Project
    (this will compile the project)
  1. Running it

  1. Switch to Java Perspective by selecting from the menu Window>Open Perspective>Other , select Java (default) and click OK
  2. In the Package Explorer highlight 01Java_HelloWorld
  3. Select Run>Run As>Java Application
  4. This will create a default run configuration called HelloWorld for the project but at the same time throw up an error as observed in the Console View. This is because the Java Virtual Machine does not yet know the path of the DLL file generated from the C Code.
  5. From the menu select Run>Run Configurations
  6. From the list within the left pane highlight HelloWorld under Java Application
  7. On the right side, switch to Arguments tab
  8. Enter VM arguments as
    -Djava.library.path="${workspace_loc}\01C_HelloWorld\Release"
  9. Click Close
  10. In the Package Explorer highlight 01Java_HelloWorld
  11. Select Run>Run As>Java Application
  12. Observe the output in the Console View
  1. References

    • Using Cygwin To Develop Windows JNI Methods
      by David Caldwell
      http://www.inonit.com/cygwin/jni/helloWorld/
    • Using The Java Native Interface
      by Christopher Batty
      http://www.cs.umanitoba.ca/~eclipse/8-JNI.pdf
    • The Java Native Interface Programmer's Guide and Specification - Getting Started
      http://java.sun.com/docs/books/jni/html/start.html
    • -mno-cygwin -- Building Mingw executables using Cygwin
      by Mumit Khan
      http://www.delorie.com/howto/cygwin/mno-cygwin-howto.html
    • MinGW’s Wikipedia Entry
      http://en.wikipedia.org/wiki/MinGW
    • Important points to note:
      • “However, because GCC does not supply its own C runtime library, MinGW's C compiler targets Microsoft's old Visual C runtime library, MSVCRT, which was released in 1998 and therefore does not include support for C99 features (let alone all of C89); while targeting MSVCRT yields programs that are as native as possible, the lack of support for C99 has caused porting problems, particularly where printf-style conversion specifiers are concerned.”

      • “MinGW forked from version 1.3.3 of Cygwin. Although both Cygwin and MinGW can be used to port Unix software to Windows, they have different approaches: Cygwin aims to provide a complete POSIX layer that provides emulations of several system calls and libraries that exist on Linux, Unix, and the BSD variants. The POSIX layer runs on top of Windows, sacrificing performance where necessary for compatibility. Accordingly, this approach requires Win32 programs written with Cygwin to run on top of a copylefted compatibility library that must be distributed with the program, along with the program's source code. MinGW aims to provide native functionality and performance via direct Windows API calls. Unlike Cygwin, MinGW does not require a compatibility layer DLL and thus programs do not need to be distributed with source code.”)



Comments