Java Native Interface for jNavigation

I’m preparing everything I need to know for this project when coding time officially starts. I’m now at the point when I have to learn how to do Java bindings for C++. I have created class that contains native methods.
[java]
package some;
public class NativeMethods {

// Declare a native method sayHello() that receives nothing and returns void
public native void sayHello();

// Declare a native method sayNumber() that receives a number and returns void
public native void sayNumber(int number);

// Declare a native method sayMyName() that receives a string and returns void
public native void sayMyName(String name);

}
[/java]

I have build it, and then when I used command javah NativeMethods.class (I went to where NativeMethods.class is, so there is no path trouble…), there is this error:

[java]
Exception in thread “main” java.lang.IllegalArgumentException: Not a valid class name: NativeMethods.class
at com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:177)
at com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:68)
at com.sun.tools.javah.JavahTask.run(JavahTask.java:509)
at com.sun.tools.javah.JavahTask.run(JavahTask.java:335)
at com.sun.tools.javah.Main.main(Main.java:46)
[/java]

I tried looking for solutions online, but none of them were helpful. Does anybody have some idea?

@Tihomir said: I have build it, and then when I used command javah NativeMethods.class (I went to where NativeMethods.class is, so there is no path trouble...), there is this error:

I don’t think javah works this way. It needs a “fully qualified class name” according to the docs. You can’t just change to the same directory as the class and run it. It takes a class argument the same way javap and java.exe do and is based on the classpath.

That helped a lot, but there were some troubles, but for the phase of generating C header command
[java]javah -classpath ~/NetBeansProjects/JavaNativeInterface/build/classes -o HelloNative.h some.NativeMethods
[/java] did the work perfectly.

Note: these should really probably be part of a build and not manually run from the command line. And in that case, the build support for javah, etc. will probably wire some stuff up for you.

I understand that. I am reading tutorials for JNI so I can see what is automatic, and what is not, so I could plan accordingly next four months.

I found some tutorial for JNI for NetBeans Beginning JNI with NetBeans IDE and C/C++ Plugin on Linux , and I’ve done almost everything like them, and in phase Implementing a Method, C project won’t build.
[java] “/usr/bin/make” -f nbproject/Makefile-Debug.mk QMAKE= SUBPROJECTS= .build-conf
make[1]: Entering directory /home/tihomir/NetBeansProjects/JNIDemoCdl' "/usr/bin/make" -f nbproject/Makefile-Debug.mk dist/libJNIdemoCdl.so make[2]: Entering directory /home/tihomir/NetBeansProjects/JNIDemoCdl’
mkdir -p build/Debug/GNU-Linux-x86
rm -f “build/Debug/GNU-Linux-x86/JNIDemo.o.d”
gcc -shared -m32 -c -g -include /usr/lib/jvm/java-7-oracle/include -fPIC -MMD -MP -MF “build/Debug/GNU-Linux-x86/JNIDemo.o.d” -o build/Debug/GNU-Linux-x86/JNIDemo.o JNIDemo.c
cc1: fatal error: /usr/lib/jvm/java-7-oracle/include: No such file or directory
compilation terminated.
make[2]: *** [build/Debug/GNU-Linux-x86/JNIDemo.o] Error 1
make[2]: Leaving directory /home/tihomir/NetBeansProjects/JNIDemoCdl' make[1]: *** [.build-conf] Error 2 make[1]: Leaving directory /home/tihomir/NetBeansProjects/JNIDemoCdl’
make: *** [.build-impl] Error 2

BUILD FAILED (exit value 2, total time: 119ms)[/java]
The only difference is the where my headers are. I checked there are definitely there.

I don’t know. I haven’t done any C programming in years and years and years… but I still know there is a difference between -include and -I (capital i)… one takes a file and the other takes a directory. And in your case you are passing a directory as a file.

I found how to to set in NetBeans when it compiles to use -I instead -include, but that didn’t work:
[java]"/usr/bin/make" -f nbproject/Makefile-Debug.mk QMAKE= SUBPROJECTS= .build-conf
make[1]: Entering directory /home/tihomir/NetBeansProjects/JNIDemoCdl' "/usr/bin/make" -f nbproject/Makefile-Debug.mk dist/libJNIdemoCdl.so make[2]: Entering directory /home/tihomir/NetBeansProjects/JNIDemoCdl’
mkdir -p build/Debug/GNU-Linux-x86
rm -f “build/Debug/GNU-Linux-x86/JNIDemo.o.d”
gcc -m32 -shared -m32 -c -g -I/usr/lib/jvm/java-7-oracle/include -fPIC -MMD -MP -MF “build/Debug/GNU-Linux-x86/JNIDemo.o.d” -o build/Debug/GNU-Linux-x86/JNIDemo.o JNIDemo.c
In file included from /usr/include/stdio.h:28:0,
from /usr/lib/jvm/java-7-oracle/include/jni.h:39,
from JNIDemo.c:1:
/usr/include/features.h:324:26: fatal error: bits/predefs.h: No such file or directory
compilation terminated.
make[2]: *** [build/Debug/GNU-Linux-x86/JNIDemo.o] Error 1
make[2]: Leaving directory /home/tihomir/NetBeansProjects/JNIDemoCdl' make[1]: *** [.build-conf] Error 2 make[1]: Leaving directory /home/tihomir/NetBeansProjects/JNIDemoCdl’
make: *** [.build-impl] Error 2[/java]
It didn’t work when I added -include and -I option, then the error was the same as previous.

Solved: Do not use NetBeans 8.0 because it’s not stable enough. Use Netbeans 7.4.

1 Like

Btw if you need some more examples, take a look at the bullet binding, and (for easier understanding of the steps) the older ant based build for it.

There are some things thats important to keep in mind.
-> the more or less reflective c access is expensive to lookup but check to invoke, kinda like with normal reflection getting the metadata stuff is the costly.
-> Some stuff gets garbagecollected on the native side, and you need to explicitly make a reference for it, to prevent that.
-> Some stuff is only valid in a single call context, if you use it outside/in the next call it contains garbage/corrupted data

And if you have native threads you always need to bind them to the JVM first if you access java from that thread, else you get very funny issues.

Wow, it is going to be harder than expected, but I like challenges. Where can I see bullet binding source code?

jme3-bullet and jme3-bullet-native projects have the source

@Empire Phoenix said: Btw if you need some more examples, take a look at the bullet binding, and (for easier understanding of the steps) the older ant based build for it.
I meant to ask if there is CSV repository of bullet binding. I think it could be very educational for me to see how the process went from beginning to the end.

Here is the one from the older svn
https://code.google.com/p/jmonkeyengine/source/browse/#svn%2Ftrunk%2Fengine%2Fsrc%2Fbullet-native%3Fstate%3Dclosed

in the git based build one should be as well