[kaffe] kaffe 1.0.6, JNI & pthreads
Clemens Fuchslocher
clfuit00@fht-esslingen.de
Mon, 6 May 2002 20:20:08 +0200 (CEST)
hi,
I have a problem with the java native interface and kaffe 1.0.6.
The following jni tasks are working without any problems: calling
a jni function from the java side and calling a java method from
the jni side. But if I try to call a java method out of a pthread,
which was created in a jni function previously, kaffe will crash
with an 'java/lang/StackOverflowError'. If I use the sun jdk it
works properly (see below).
System:
-=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-=
zero:~$ uname -a
Linux foo 2.4.17 #1 Sat Apr 13 17:34:00 CEST 2002 i686 unknown
zero:~$ /lib/libc.so.6
GNU C Library stable release version 2.2.5, by Roland McGrath et al.
[...]
Compiled by GNU CC version 2.95.4 20011006 (Debian prerelease).
Compiled on a Linux 2.4.13 system on 2002-02-04.
Available extensions:
GNU libio by Per Bothner
crypt add-on version 2.1 by Michael Glad and others
linuxthreads-0.9 by Xavier Leroy
BIND-8.2.3-T5B
libthread_db work sponsored by Alpha Processor Inc
NIS(YP)/NIS+ NSS modules 0.19 by Thorsten Kukuk
Report bugs using the `glibcbug' script to <bugs@gnu.org>.
zero:~$ java -version
Kaffe Virtual Machine
Copyright (c) 1996-2000
Transvirtual Technologies, Inc. All rights reserved
Engine: Just-in-time v3 Version: 1.0.6 Java Version: 1.1
zero:~$ javac -version
version number: 1.4F released 05/23/2000
zero:~$ kaffeh -version
Kaffeh Stub Generator
Copyright (c) 1996, 1997
Transvirtual Technologies, Inc. All rights reserved
Version: 1.0.6
-=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-=
Here is an example that produces the error mentioned above:
-=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-=
// Test.java
class Test
{
long c = 0;
public native void test_start_callback ();
public native void test_stop_callback ();
static
{
try
{
System.loadLibrary ("test");
}
catch (Exception e)
{
System.err.println ("System.loadLibrary (): " + e);
System.exit (1);
}
}
public void start ()
{
test_start_callback ();
}
public void stop ()
{
test_stop_callback ();
}
public void callback ()
{
System.out.println ("public void callback (): " + c++);
}
}
class Main
{
public static void main (String args[])
{
Test test = new Test ();
test.start ();
try
{
System.in.read ();
}
catch (Exception e)
{
System.err.println (e);
System.exit (1);
}
test.stop ();
}
}
-=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-=
test_jni.c:
-=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-=
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <jni.h>
#include <pthread.h>
#include "Test.h"
pthread_t thread;
JavaVM *vm = NULL;
jobject obj;
static int end = 1;
static void *test_thread (void *arg)
{
JNIEnv *env = NULL;
jclass class;
jmethodID callback;
if ((*vm)->AttachCurrentThread (vm, (JNIEnv **) &env, NULL) < 0)
{
fprintf (stderr, "%s[%d]: AttachCurrentThread ()\n",
__FILE__, __LINE__);
return NULL;
}
class = (*env)->GetObjectClass (env, obj);
callback = (*env)->GetMethodID (env, class, "callback", "()V");
if (callback == NULL)
{
fprintf (stderr, "%s[%d]: GetMethodID ()\n",
__FILE__, __LINE__);
return NULL;
}
while (end)
{
(*env)->CallVoidMethod(env, obj, callback);
sleep (1);
}
if ((*vm)->DetachCurrentThread (vm) < 0)
{
fprintf (stderr, "%s[%d]: DetachCurrentThread ()\n",
__FILE__, __LINE__);
return NULL;
}
return NULL;
}
JNIEXPORT void JNICALL
Java_Test_test_1start_1callback (JNIEnv *env, jobject object)
{
int ret;
end = 1;
printf ("JNI: test_start_callback ()\n");
if ((*env)->GetJavaVM (env, &vm) < 0)
{
fprintf (stderr, "%s[%d]: GetJavaVM ()\n",
__FILE__, __LINE__);
return;
}
obj = (*env)->NewGlobalRef (env, object);
if (obj == NULL)
{
fprintf (stderr, "%s[%d]: NewGlobalRef ()\n",
__FILE__, __LINE__);
return;
}
if ((ret = pthread_create (&thread, NULL, test_thread, NULL)) != 0)
{
fprintf (stderr, "%s[%d]: pthread_create (): %s\n",
__FILE__, __LINE__, strerror (ret));
return;
}
}
JNIEXPORT void JNICALL
Java_Test_test_1stop_1callback (JNIEnv *env, jobject object)
{
int ret;
printf ("JNI: test_stop_callback ()\n");
end = 0;
if ((ret = pthread_join (thread, NULL)) != 0)
{
fprintf (stderr, "%s[%d]: pthread_join (): %s\n",
__FILE__, __LINE__, strerror (ret));
return;
}
(*env)->DeleteGlobalRef (env, obj);
}
-=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-=
This is how I build the jni application with kaffe:
-=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-=
zero:~$ export LD_LIBRARY_PATH=.
zero:~$ export PATH=/usr/local/kaffe/bin:$PATH
zero:~$ export CLASSPATH=.:/usr/local/kaffe/share/kaffe/Klasses.jar
zero:~$ javac Test.java
zero:~$ kaffeh -jni Test
zero:~$ gcc -Wall -I/usr/local/kaffe/include/kaffe/ -c test_jni.c
zero:~$ gcc -shared -Wl,-soname,libtest.so -o libtest.so test_jni.o \
-lpthread
-=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-=
The crash:
-=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-=
zero:~$ java Main
JNI: test_start_callback ()
Internal error: caught an unexpected exception.
Please check your CLASSPATH and your installation.
java/lang/StackOverflowError
Aborted (core dumped)
[...]
zero:~$ java Main
JNI: test_start_callback ()
Kaffe: machine.c:214: translate: Assertion `reinvoke == false'
failed.
Aborted (core dumped)
[...]
zero:~$ java Main
JNI: test_start_callback ()
Kaffe: exception.c:372: dispatchException: Assertion
`!intsDisabled()' failed.
Aborted (core dumped)
-=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-=
If I use the sun jdk 1.3.1/1.4.0 instead, everything works fine.
-=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-=
zero:~$ export LD_LIBRARY_PATH=.
zero:~$ javac Test.java
zero:~$ javah -jni Test
zero:~$ gcc -Wall -c test_jni.c
zero:~$ gcc -shared -Wl,-soname,libtest.so -o libtest.so test_jni.o \
-lpthread
zero:~$ java Main
JNI: test_start_callback ()
public void callback (): 0
public void callback (): 1
public void callback (): 2
[...]
public void callback (): 40
public void callback (): 41
public void callback (): 42
JNI: test_stop_callback ()
zero:~$
-=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-= -=-=
What's wrong?
--