[Kde-java] GCJ and qtjava/kdejava
Richard Dale
kde-java@kde.org
Fri, 8 Mar 2002 01:50:29 +0000
On Wednesday 06 March 2002 8:38 pm, Adam Dingle wrote:
> I've spent the last few days getting GCJ to work with the qtjava and
> kdejava bindings from the kdebindings package. I've finally got everything
> working fine, but it took me a while to get there, and so I thought I'd
> share my experiences. I'm using Red Hat Linux 7.2.
>
> First and foremost: if you want to use GCJ with KDE, you REALLY want to use
> GCC 3.0.4. I tried several other versions of GCC/GCJ and had trouble with
> all of them, as follows:
>
> - GCJ 2.x doesn't work at all because the qtjava bindings rely on weak
> references and on certain Java utility classes which are present only in
> GCJ 3.x.
>
> - When I use GCJ 3.0.1, at least as packaged by Red Hat and distributed
> with Red Hat Linux 7.2, then I can build a Qt program with GCJ, but the
> program hangs almost immediately upon running it. This is the behavior
> which Thomas Kuhn reported to this mailing list when he tried to use GCJ
> with qtjava last August (see
> http://lists.kde.org/?l=kde-java&m=99844128813679&w=2). Thomas attributed
> this hang to JNI problems in GCJ, and I am inclined to agree withwhen him.
> He worked around the problem by changing some of the qtjava code to use
> CNI, but I've found that using a newer GCJ also solves the problem.
This is really good news if the source doesn't need any changes to build with
gcj.
> - I also tried using a prerelease of GCJ 3.1 from Red Hat's Rawhide
> distribution, the gcc-3.1-0.21 package (OK, I know I was really asking for
> trouble here). With this GCJ, I was able to built a small Java program
> that used qtjava and my program ran, but crashed on exit. I spent some
> time debugging and found that the crash occurred in GCJ's JNI runtime code
> as it was freeing local references (see the JNI spec for information about
> these) on exit from my QApplication's exec() method. I haven't had time to
> debug this more, but I believe that this is either a JNI bug or a bug in
> GCJ 3.1's IdentityHashMap class which the JNI code uses to hold reference
> counts for local references.
The bindings have JNI local leaks - I fixed quite a few leaks in the Qt 3 HEAD
branch - so there may be excessive local references at the top level in
QApplication.exec().
> But, happily, everything works fine if I use GCJ 3.0.4 (which I had to
> build myself, since I haven't found a Red Hat binary for this GCC anywhere
> out there). Would GCJ 3.02 or 3.03 work? I don't know.
Here is the crash I got when I tried gcc 3.0.3 - I've already sent it to Adam,
but here it is again for completeness. The gcj code threw an exception on
returning from the first JNI function called:
tipitina duke 1491% HelloWorld
In registerJVM..
Exception in thread "main" java.lang.ExceptionInInitializerError:
java.lang.NullPointerException
at 0x0f81dab0: _Jv_ThrowSignal (/usr/local/lib/libgcj.so.2)
at 0x0f81dae8: _Jv_equalUtf8Consts(_Jv_Utf8Const, _Jv_Utf8Const)
(/usr/local/lib/libgcj.so.2)
at 0x7ffff258: _r_debug (/lib/ld.so.1)
at 0x0f8204c8: _Jv_JNI_Init() (/usr/local/lib/libgcj.so.2)
at 0x0f82056c: _Jv_JNI_PopSystemFrame (/usr/local/lib/libgcj.so.2)
at 0x0fe91b44: org.kde.qt.qtjava.registerJVM()
(/export/src/gcjbindings/qtjava/javalib/org/kde/qt/libqtjavaiface.so)
at 0x0fe93ac0: org.kde.qt.qtjava.__U3c_clinit__U3e_()
(/export/src/gcjbindings/qtjava/javalib/org/kde/qt/libqtjavaiface.so)
at 0x0f83b68c: java.lang.Class.initializeClass()
(/usr/local/lib/libgcj.so.2)
...
But perhaps this only happens on PowerPC, and not Intel.
> Here's some more advice if you want to get this working. You should
> compile the Java code in the qtjava and kdejava packages to libraries of
> native code; then you won't have to compile that code each time you build
> your own Java applications. I added the following to
> kdebindings-2.2.2/qtjava/javalib/org/kde/qt/Makefile.am:
>
> GCJ = gcj --classpath=$(CLASSPATH):/usr/share/libgcj.jar
> GCJFLAGS = -fPIC -fjni
> libqtjavaiface.so: $(EXTRA_DIST)
> $(GCJ) $(GCJFLAGS) -shared $(EXTRA_DIST) -o $@
>
> And I added the following to
> kdebindings-2.2.2/kdejava/koala/org/kde/koala/Makefile.am:
>
> GCJ = gcj --classpath=$(CLASSPATH):/usr/share/libgcj.jar
> GCJFLAGS = -fPIC -fjni
> libkdejavaiface.so: $(EXTRA_DIST)
> $(GCJ) $(GCJFLAGS) -shared $(EXTRA_DIST) -o $@ \
> -L../../../../../qtjava/javalib/org/kde/qt -lqtjavaiface
>
> (The library names "libqtjavaiface.so" and "libkdejavaiface.so" are the
> same ones Thomas Kuhn used with his kdebindings patches, which Richard Dale
> emailed along to me.)
It would be nice to add some sort of option to configure in kdebindings - eg
'--enable-gjc', which would build the extra libs. It's much easier now that
Thomas's CNI callbacks aren't needed.
> With these rules in place, build libqtjavaiface.so and libkdejavaiface.so.
> Copy them to your /usr/lib directory. Now you can build the ScribbleWindow
> example from qtjava like this.
>
> gcj ScribbleWindow.java -o scribble --main=ScribbleWindow -lqtjavaiface
>
> And, at least on my machine, it works!
I'm very envious! This is the best news about gcj since Thomas got it working
in the first place. I must try gcc 3.0.4 on PowerPC, and hope it works better
than 3.0.1 or 3.0.3 that I've tried.
-- Richard