[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

native threads and Invocation API

Hash: SHA1

I'm having a problem with native threads and the Invocation API.  I
think that the JDK1.1 native threads package is built incorrectly and
requires glibc2.0 symbols.  This breaks on my unstable system, which
has glibc2.1 installed.

Here is a simple program that just tries to load and run a class that
has the same name as the executable:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <jni.h>

int main(int argc, char *argv[])
    JNIEnv *env;
    JavaVM *jvm;
    JDK1_1InitArgs vm_args;
    char *newcp;
    jint result;
    vm_args.version = 0x00010001;
    char *envclasspath = getenv("CLASSPATH");

    if (envclasspath)
      vm_args.classpath = envclasspath;

    result = JNI_CreateJavaVM(&jvm, &env, &vm_args);

    if (result)
        fprintf(stderr, "Can't create JVM.  Error: %ld\n", result);
        return 1;

    jclass clazz = env->FindClass(argv[0]);

    if (!clazz)
        fprintf(stderr, "Could not find the class '%s'.\n", argv[0]);
        return 1;

    jmethodID mid = env->GetStaticMethodID(clazz, "main",

    if (!mid)
        fprintf(stderr, "Can't locate the main method.\n");
        return 1;

    jstring jstr = env->NewStringUTF("");
    jobjectArray str_array =
        env->NewObjectArray(argc - 1, env->FindClass("java/lang/String"), jstr);

    for (int i = 1; i < argc; i++)
        jstr = env->NewStringUTF(argv[i]);
        if (!jstr)
            fprintf(stderr, "Could not create a string from '%s'\n.", argv[i]);
            return 1;
        env->SetObjectArrayElement(str_array, i - 1, jstr);

    env->CallStaticVoidMethod(clazz, mid, str_array);
    return 0;

I compile it with this:
g++ invoketest.c -o invoketest -I/usr/lib/jdk1.1/include \
- -L/usr/lib/jdk1.1/lib/i386/green_threads -ljava -L/usr/X11R6/lib -lXm \
- -lXt -lXext -lX11

That works fine.  But if I try to compile it with native threads
instead by changing the above line to:
g++ invoketest.c -o invoketest -I/usr/lib/jdk1.1/include \
- -L/usr/lib/jdk1.1/lib/i386/native_threads -ljava -L/usr/X11R6/lib -lXm \
- -lXt -lXext -lX11

I get a link-time error of:
/usr/lib/jdk1.1/lib/i386/native_threads/libjava.so: undefined reference to `sem_destroy@@GLIBC_2.0'
/usr/lib/jdk1.1/lib/i386/native_threads/libjava.so: undefined reference to `sem_post@@GLIBC_2.0'
/usr/lib/jdk1.1/lib/i386/native_threads/libjava.so: undefined reference to `sem_wait@@GLIBC_2.0'
/usr/lib/jdk1.1/lib/i386/native_threads/libjava.so: undefined reference to `sem_init@@GLIBC_2.0'
collect2: ld returned 1 exit status

Here are the relevant packages that are installed:
ii  jdk1.1          1.1.7v2-2      JDK 1.1.x (Java Development Kit) - Runtime o
ii  jdk1.1-dev      1.1.7v2-2      JDK 1.1.x (Java Development Kit)
ii  jdk1.1-native   1.1.7v2-2      JDK 1.1.x Runtime - native threads extension
ii  jdk1.1-native-d 1.1.7v2-2      JDK 1.1.x - native threads extensions
ii  libc6           2.1.2-0pre11   GNU C Library: Shared libraries and timezone
ii  libc6-dev       2.1.2-0pre11   GNU C Library: Development libraries and hea

Also, this example program demonstrates a problem.  If a program wants 
to use the Invocation API, it can set up the CLASSPATH so that it
doesn't need to be set before the program runs.  However, at least
with the JDK package, the LD_LIBRARY_PATH has to be set to include
/usr/lib/jdk1.1/lib/i386/{native,green}_threads or it will not be able 
to find libjava.so.  The kaffe package gets around this by putting
libkaffevm.so, which has the Invocation API interface, in /usr/lib.

Should the Debian policy for Java include the location of the .so so
that programs that use the Invocation API can have a standard link

- -- 
Gene McCulley                                          Voice: (407) 265-0772
mcculley@enki.org                                        Fax: (407) 265-0773
Version: GnuPG v0.9.10 (GNU/Linux)
Comment: For info see http://www.gnupg.org


Reply to: