Contacts, GCJ, Retroweaver

I spent some time today getting my Java Gnome Contacts application compiling and running with GCJ. It went really well in the end; but there were lots of gotchas that I’d like to talk digress into.

Firstly I decided to prioritize this over feature additions as a result of a quick communication with a Java Gnome hacker. The spirit of getting Java Gnome applications running with gcj is obvious… Free Software. I’ve taken this to heart; and will endeavour to have an automated gcj build of my apps alongside all my future Java Gnome development.

Contacts uses Java 1.5 language features. I’m not going to change this as I like my for each loops and my generics too much. Given that gcj does not currently support 1.5, I first looked into Retroweaver as a means to get my 1.5 classes to a 1.4 binary compatibility state.

After placing the Retroweaver library in my ant/lib directory, I run the following ant target.

<target name="retroweave">
    <taskdef name="retroweaver"
             classname="com.rc.retroweaver.ant.RetroWeaverTask"/>
    <retroweaver classpathref="modular-build.path">
        <fileset dir="${modular-build.dir}">
            <include name="**/*.class"/>
        </fileset>
    </retroweaver>
</target>

presuming
Where ${modular-build.dir} is the root of my modular build folder… essentially containing my existing 1.5 classes and modular-build.path is a classpath reference to a list of package dependencies – jdom / junit / commons-codec / java gnome / etc…

It worked perfectly after making a number of code changes:

  • Removing all String.contains calls; I replaced with a StringUtils.contains() call
  • Removing all String.replace(CharSequence target, CharSequence replacement) calls; I replaced with the regex replace method
  • I was using the BASE64Encoder class in sun.misc; Instead I replaced with commons-codec calls

It successfully reports weaving and verifying X number of classes; so I trust it – and move on to getting a gcj target up and running. Gcj will take and compile java source files; but in my case I’ve already got compiled classes… which isn’t a problem as gcj will happilly support classes as input too.

To make things easy on myself the next target was actually a jar task that packages all my little modules into one grand java-gnome-contacts-all.jar

I’m new to gcj; so finding the correct damned compile command took me a while. When using gcj 3.x.x one needs to compile all package dependencies as shared libraries with something like the following command:

gcj -shared jdom.jar -o libjdom-1.0.so

… and then in turn link against the libjdom-1.0.so with -ljdom-1.0 when you’re compiling your own application. The dream turns into a nightmare when you realize you also need jaxen which depends on xom/dom4j/xerces and all those in turn have their own dependencies. What I didn’t realise was gcj 4.x.x has a cool magic flag -findirect-dispatch which according to the man page when used: ” the resulting object files do not need to be directly linked against their dependencies. Instead, all dependencies are looked up at runtime.” Now I’ll be honest and dont fully understand what looked up at runtime means – but I’m presuming that as long as the package dependency jar is in the CLASSPATH at runtime – all will work fine.

In the end the gcj compile command was as simple as the following:

gcj --main=com.excentric.contacts.Main java-gnome-contacts-all.jar
-findirect-dispatch -o JavaGnomeContacts

I have resources that I need in a relative working directory… so once I place the binary just beneath the resources directory and export my CLASSPATH correctly… Java Gnome Conacts runs… Wahey!

All in all, I’m very impressed with both Retroweaver and obviously more so gcj. I can now see a path to where I can throw a contacts binary into a local apt repository and expose it to the world.

On a side note: contacts currently uses java serialization to persist until I settle on a db. (db4o is what I’m going to look at next, recommended to me by Java Gnome’s AfC) And it appears that the serialization and deserializationis is very slow in gcj compared to when I run it under a jvm.

One Response to “Contacts, GCJ, Retroweaver”

  1. Antony Says:

    http://retrotranslator.sourceforge.net is another project like Retroweaver, but supports String.contains, String.replace etc

Leave a Reply

You must be logged in to post a comment.