drinking too much kaffe
Posted on 2007-03-20 09:51:30 EET.
I tried to write simple midgard-java jni based bindings , but unfortunatelly got few not interesting issues.
If you follow almost every JNI specifications and docs and examples, you should run command like:
javah -jni org_midgardproject_connection
Not expected output is:
Failed to open object 'org_midgardproject_connection'
I was wondering what is the case as it worked perfect few days ago with HelloWorld example. And problem seems to be in some package being overwritten or removed or updated. I made few java related packages reinstall when I wanted to compile latest java-gnome. No success, though :/
Solution here is simple:
javah -classpath . -jni org_midgardproject_connection
Next problem is more difficult. When I compiled my org_midgardproject_connecion , I tried to run my new java script:
java -Djava.library.path=`pwd` org_midgardproject_connection arg
And exception:
Exception in thread "main" java.lang.UnsatisfiedLinkError: Open at org_midgardproject_connection.main(org_midgardproject_connection.java:38)
Solution here is to "tweak" header and source file , which is badly created by javah tool.
JNIEXPORT jboolean JNICALL Java_org_midgardproject_connection_Open(JNIEnv*, jobject, jstring);
There are no '1' after underscores. So function prototype should look like this:
JNIEXPORT jboolean JNICALL Java_org_1midgardproject_1connection_Open(JNIEnv*, jobject, jstring);
After this change everything seems to be working very nice.
Aha, just in case if you would like to write midgard-java bindings. Compile it like this:
gcj -shared `pkg-config --libs --cflags midgard` org_midgardproject_connection.c -o libmidgard-java.so
So now, java code looks like this:
class org_midgardproject_connection
{
public native boolean Open(String name);
private static native boolean SetSitegroup(String guid);
private static native String GetSitegroup();
public static void main(String[] args) {
new org_midgardproject_connection().Open(args[0]); }
static {
System.loadLibrary("midgard-java");
}
}
And simple JNI C code:
JNIEXPORT jboolean JNICALL
Java_org_1midgardproject_1connection_Open
(
JNIEnv *env,
jobject _object,
jstring _name
)
{
g_type_init();
MidgardConnection *mgd = midgard_connection_new();
gchar *name = (gchar*) (*env)->GetStringUTFChars(env, _name, NULL);
gboolean rv;
rv = midgard_connection_open(mgd, name, NULL);
(*env)->ReleaseStringUTFChars(env, _name, name);
return (jboolean) rv;
}
I tried java script being logged in as custom user, and midgard-core tried to open configuration file from /etc. So I got "Permission denied".
Looks like it is working :)