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 :)

Back

Layout Copyright © 2006 Finnish Teleservice Center Ltd Oy - Site Powered by Midgard CMS