[e-lang] E-on-Java works with recent gcj

Toby Murray toby.murray at dsto.defence.gov.au
Fri Aug 11 03:41:04 EDT 2006


Hi e-lang,

A little while ago,  Eric Northup wrote about his experience with gcj to 
compile a native version of E.
(see http://www.eros-os.org/pipermail/e-lang/2006-June/011318.html)
I've recently been trying to reproduce his results and include some 
findings below.

Essentially: I could get a "MetaRune" binary built, although it needed 
access to the built .class files at runtime. I was puzzled by this 
because I could see the mangled symbols from the offending classes that 
it was trying to load inside the "MetaRune" binary by using 'nm'. This 
is vexing. Eric, did you have the same issue? (see below for how I 
overcame the few stumbling blocks that presented themselves).

My "MetaRune" binary could run an AWT application, which was nice to 
see. It was built from E sources of the 0.8.35f version.
A quick performance test comparing it to Java 1.5_05 JRE running e.jar 
from 0.8.35f "purej" showed that it performs only marginally better.
My "MetaRune" binary completed an execution of a "Hello World" program 
in around 2.74 seconds (although timings varied from about 2.6 to 3.1 secs).
JRE 1.5.0_05 running e.jar from 0.8.35f completed the same execution in 
around 2.94 seconds.

I was working on a Fedora Core 5 box with the E sources from version 
0.8.35f (ie. 
http://www.cypherpunks.to/erights/download/0-8-35/E-src-0.8.35f.tar.gz)

[As a side note, I would recommend either removing the "*** This page to 
be rewritten" note on the Download page, or rewriting the page for good. 
>From memory, that note has been there for quite some time and tends to 
give the impression that development might have stalled, although I know 
it hasn't.]

I unpacked the sources into a directory and from within the main src 
directory used Eric's build-e-gcj.sh script.
First I had to make the same change to SWTRunner.java as Eric.

Eric Northup wrote:

>I had to make a few changes to E's java source to get things to build.
>
>diff -ru src/jsrc/org/erights/e/ui/swt/SWTRunner.java
>/home/eric/n/e/src/jsrc/org/erights/e/ui/swt/SWTRunner.java
>--- src/jsrc/org/erights/e/ui/swt/SWTRunner.java        2006-05-31
>19:36:03.000000000 -0400
>+++ /home/eric/n/e/src/jsrc/org/erights/e/ui/swt/SWTRunner.java
>2006-05-31 20:31:37.000000000 -0400
>@@ -109,7 +109,9 @@
>
>                 // XXX Happens too late to effect rune(["--version"])
>                 System.setProperty("e.swtVersion",
>""+SWT.getVersion());
>-//                System.setProperty("e.swtRevision",
>""+Library.getRevision());
>+// XXX doesn't work on gcj
>+//            System.setProperty("e.swtRevision",
>""+Library.getRevision());
>+//
>                 System.setProperty("e.swtPlatform", SWT.getPlatform());
>             }
>             return THE_DEFAULT;
>  
>
Unlike Eric, I didn't need to modify Native.java (although I'm not so 
sure my build ended up in the same state as his, although all of the 
elements of his script completed successfully).

I used his script, below:

><<<< begin build-e-gcj.sh >>>>
>
>#!/bin/sh
>                                                                                                                                                                                                     
>SWT_JARPATH=/usr/share/java/swt-gtk-3.1.1.jar
>SWT_LIBDIR=/usr/lib
>SWT_LIB=swt-gtk-3139
>MAIN_CLASS=org.erights.e.elang.interp.MetaRune
>                                                                                                                                                                                                     
>rm -rf BUILD
>mkdir -p BUILD/class BUILD/obj BUILD/lib
>javafiles=`find . -name '*.java'`
>                                                                                                                                                                                                     
># Compile + check .java files into .class files
>gcj -C -I. -I$SWT_JARPATH -d BUILD/class $javafiles
>                                                                                                                                                                                                     
># We're going to compile BUILD/class/module/.../name.class ->
># BUILD/obj/module/.../name.o.  We just go straight to BUILD/obj/name.o
>if we
># knew that no classes existed with conflicting names.  (This almost
>seems
># true of the E build, but Antlr has a bunch of exceptions).
>                                                                                                                                                                                                     
>dir_list=""
>for javafile in $javafiles; do
>    dir_list="$dir_list
>`dirname $javafile`"
>done
>                                                                                                                                                                                                     
>dir_list=`echo -n "$dir_list" | sort -u`
>                                                                                                                                                                                                     
>for a_dir in $dir_list; do
>    mkdir -p BUILD/obj/$a_dir
>done
>                                                                                                                                                                                                     
>all_dotos=""
>                                                                                                                                                                                                     
># Compile .class files into .o files
>for javafile in $javafiles; do
>    path=`dirname $javafile`
>    name=`basename $javafile .java`
>    this_doto=BUILD/obj/$path/$name.o
>    all_dotos="$all_dotos $this_doto"
>    echo $javafile '.class -> .o'
>    echo gcj -IBUILD/obj -IBUILD/class -I$SWT_JARPATH \
>        -c $javafile -o $this_doto
>    gcj -IBUILD/obj -IBUILD/class -I$SWT_JARPATH \
>        -c $javafile -o $this_doto || exit 1
>done
>                                                                                                                                                                                                     
>ar -crs BUILD/lib/lib$MAIN_CLASS.a $all_dotos
>                                                                                                                                                                                                     
>echo gcj --main=$MAIN_CLASS -I. -I$SWT_JARPATH -o $MAIN_CLASS
>BUILD/lib/*.a -L$SWT_LIBDIR -l$SWT_LIB
>gcj --main=$MAIN_CLASS -I. -I$SWT_JARPATH -o $MAIN_CLASS BUILD/lib/*.a
>-L$SWT_LIBDIR -l$SWT_LIB
>
>
><<<< end build-e-gcj.sh >>>>
>
>This produces an executable binary org.erights.e.elang.interp.MetaRune.
>
>Running the binary should be equivalent to running "java -jar e.jar".
>
>  
>
First running the binary complained it couldn't find "<some 
path>/syntax-properties-default.txt" (or something like that. I don't 
have the results in front of me anymore)
The file it was looking for was located in the bin/resources/ subdir. 
Running the MetaRune binary from there overcomes this error.  (As does 
adding the full path to the bin/resources directory to the CLASSPATH).

It then reported that it couldn't load the HeadlessRunnerMgr class. (A 
ClassNotFoundException from memory). This seems strange because the 
corresponding symbols for the HeadlessRunnerMgr class are definitely 
within the MetaRune binary. Can anyone enlighten me on how the 
classloader from libgcj works and whether it can dynamically load 
classes built into a binary?

Eric's script places the built class files into the BUILD/class subdir. 
Setting the CLASSPATH to the full path to that directory overcomes this 
particular error.

At this point, MetaRune complains that it can't find a (forgotten... 
sorry) class, which is implemented by E code in the esrc/ subdirectory. 
Adding the full path to the esrc/ subdirectory to the CLASSPATH 
overcomes this error and allows "MetaRune" to run properly.

Essentially, I was able to get the 'org.erights.e.elang.interp.MetaRune' 
binary to run from the source directory by doing something like this (in 
bash):
CLASSPATH=$PWD/bin/resource:$PWD/BUILD/class:$PWD/esrc 
./org.erights.e.elang.interp.MetaRune --rune

I'd love to hear of anyone else's experience with this. Would be great 
to see a native rune binary up and running properly.

Thanks
Toby

-- 
Toby Murray
Advanced Computer Capabilities Group
Information Networks Division
DSTO, Australia

IMPORTANT: This e-mail remains the property of the Australian Defence
Organisation and is subject to the jurisdiction of section 70 of the
Crimes Act 1914. If you have received this e-mail in error, you are
requested to contact the sender and delete the e-mail.



More information about the e-lang mailing list