[Kde-java] Installation Question

Richard Dale kde-java@kde.org
Sat, 1 Feb 2003 17:53:56 +0000


On Saturday 01 February 2003 3:12 pm, Marco Ladermann wrote:
> On Freitag, 31. Januar 2003 13:32, Richard Dale wrote:
> > People have reported problems with hotspot on 1.3 and 1.4 jvms, so you
> > may need to turn off hotspot if you have unexpected crashes.
>
> My QtJava programs crashes all the time with the library that comes from
> the kdebindings.rpm (upto KDE 3.1, SuSE 8.1 rpm's) and jvm's >= 1.3. I'm
> pretty sure that it is some threading issue. Two workarounds let me run
> them anyway:
>
> 1) Use the "-green" switch with a 1.3 jvm
> 2) Build from the sources and link libqtjava.so against libqt.so and NOT
> libqt-mt.so
>
> (I prefer the second approach)
>
> Here are two versions of the messages spit out by the jvm (1.4) while
> running/aborting the same program two times:
>
> a)
> An unexpected exception has been detected in native code outside the VM.
> Unexpected Signal : 11 occurred at PC=0x400AE7CE
> Function=(null)+0x400AE7CE
> Library=/lib/libc.so.6
>
> b)
> An unexpected exception has been detected in native code outside the VM.
> Unexpected Signal : 11 occurred at PC=0x4002F0CD
> Function=__pthread_mutex_lock+0x1D
> Library=/lib/libpthread.so.0
Hmm, tricky. I'm still using a 1.2.2 jvm, so I can't repeat it. I tried to 
upgrade to jdk 1.3, but it needed glibc 2.2.4 or later, and upgrading to that 
would mean I'd have to rebuild just about everything. I really need to wipe 
my machine and get a newer Linux distribution installed.

The bindings don't use threads, with the exception of the finalizer thread 
calling the finalize() methods. Perhaps when the C++ instances are deleted in 
the finalize() methods, it messes up the main thread.

The QtJava finalize() methods look like this:

JNIEXPORT void JNICALL
Java_org_kde_qt_QFont_finalize(JNIEnv *env, jobject obj)
{
	if (QtSupport::allocatedInJavaWorld(env, obj)) {
		delete (QFont*)QtSupport::getQt(env, obj);
		QtSupport::setQt(env, obj, 0);
	}
	return;
}

They always call the boolean method 'QtSupport::allocatedInJavaWorld()' and 
only delete the C++ instance if it returns TRUE. To confirm whether or not 
this is the problem, it should be possible to change allocatedInJavaWorld() 
to always return FALSE.

bool
QtSupport::allocatedInJavaWorld(JNIEnv * env, jobject obj)
{
	if (obj == 0) {
		return FALSE;
	}

	jclass cls = env->GetObjectClass(obj);
	bool result = (bool) env->GetBooleanField(obj, env->GetFieldID(cls, 
"_allocatedInJavaWorld", "Z"));
	env->DeleteLocalRef(cls);
	return result;
}

ie change it to this in qtjava/javalib/QtSupport.cpp:

bool
QtSupport::allocatedInJavaWorld(JNIEnv * env, jobject obj)
{
	return FALSE;
}

Then start java with the gc logging option on, and see if the problem goes 
away. If this is the problem, the finalize() methods would need to send a 
custom QEvent to the main thread with the address of the instance to be 
deleted. Then the actual deletion would be done in the main thread. But then 
again the problem might not be to do with finalizer thread, so no point in 
doing too much designing yet until we've pinned it down a bit better.

-- Richard