Static Linking Problem
Alan Eliasen
eliasen@mindspring.com
Sat Nov 17 10:59:00 GMT 2007
I've been trying to create a standalone executable for my programming
language "Frink" ( http://futureboy.us/frinkdocs/ ) and have succeeded
rather easily using Mohan Embar's port of GCJ to Windows (although it
blows my computer out of virtual memory (1 GB+) after running for over
an hour when optimization is turned on!), but I'm having difficulties
with the Linux version. I can successfully compile and run an
executable that's linked to the shared versions of libgcj and libgcc,
but can't get a static executable to work properly.
I've reduced this to a small test case. This is a file called
DateTest.java:
public class DateTest
{
public static void main(String[] args)
{
java.text.DateFormat df=java.text.DateFormat.getDateTimeInstance();
System.out.println(df.toString());
}
}
and compiling using:
gcj -c DateTest.java
gcj -static-libgcj -static-libgcc --main=DateTest -o DateTest DateTest.o
However, when I try to run this program, I get the following error:
Exception in thread "main" java.lang.ExceptionInInitializerError
at java.lang.Class.initializeClass(natClass.cc:792)
at java.util.Currency.getInstance(Currency.java:290)
at java.text.DecimalFormatSymbols.<init>(DecimalFormatSymbols.java:161)
at
java.text.DecimalFormatSymbols.getInstance(DecimalFormatSymbols.java:718)
at java.text.NumberFormat.computeInstance(NumberFormat.java:335)
at java.text.NumberFormat.getNumberInstance(NumberFormat.java:486)
at java.text.SimpleDateFormat.<init>(SimpleDateFormat.java:451)
at java.text.DateFormat.computeInstance(DateFormat.java:644)
at java.text.DateFormat.getDateTimeInstance(DateFormat.java:799)
at DateTest.main(DateTest)
Caused by: java.lang.NullPointerException
at java.io.InputStreamReader.read(DateTest)
at java.io.BufferedReader.fill(DateTest)
at java.io.BufferedReader.readLine(DateTest)
at java.util.Properties.load(DateTest)
at java.util.Currency.<clinit>(DateTest)
at java.lang.Class.initializeClass(DateTest)
at java.util.Currency.getInstance(DateTest)
at java.text.DecimalFormatSymbols.<init>(DateTest)
at java.text.DecimalFormatSymbols.getInstance(DateTest)
at java.text.NumberFormat.computeInstance(DateTest)
at java.text.NumberFormat.getNumberInstance(DateTest)
at java.text.SimpleDateFormat.<init>(DateTest)
at java.text.DateFormat.computeInstance(DateTest)
at java.text.DateFormat.getDateTimeInstance(DateTest)
...1 more
It appears to be failing to load the java.util.Currency class.
(Which is of course unnecessary.) I've tried adding hack to try and
force loading of java.util.Currency in the file above, like these:
java.util.Currency dog = java.util.Currency.getInstance("USD");
System.out.println(dog.toString());
but still get the same problems (inability to initialize the Currency
class, which is, again, not needed or used, and this unnecessary
dependency is causing slower startups and problems.) It may be a
problem with loading locale files. There are probably better ways to
handle a missing locale than for class initialization to fail entirely
and throw exceptions up the whole stack, though.
So, my question is: is there something that can be done to allow
this statically-linked executable to work? I'd hate to have to list and
dummy-load all possible date formats and currencies for all locales in
the world just to format dates for the user's default locale. (I'm not
even using Currencies!) Can this situation be improved?
It makes static linking near-impossible, and this makes distribution
of programs compiled with gcj unworkable. (I don't want to ship my
particular libgcj.so with the executables!)
Again, it works okay with a shared executable, but not with the
static flags above. I understand that gcj will not link unused classes,
but hopefully something can be done to make simple programs like this
work properly. (And hopefully the dependence of Date classes on
Currency classes can be broken!)
By the way, my locale is:
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
I'm using today's trunk under Fedora Core 7:
uname -a
Linux feynman 2.6.23.1-21.fc7 #1 SMP Thu Nov 1 20:28:15 EDT 2007 x86_64
x86_64 x86_64 GNU/Linux
gcj version:
Using built-in specs.
Reading specs from
/home/eliasen/builds/gccbin/lib/gcc/x86_64-unknown-linux-gnu\
/4.3.0/../../../libgcj.spec
rename spec startfile to startfileorig
rename spec lib to liborig
Target: x86_64-unknown-linux-gnu
Configured with: ../gcc/configure --prefix=/home/eliasen/builds/gccbin
--with-x\
--with-gmp=/home/eliasen/builds/gmpbuild
--with-mpfr=/home/eliasen/builds/mpfr\
build --enable-shared --enable-threads=posix --enable-languages=java
Thread model: posix
gcc version 4.3.0 20071116 (experimental) (GCC)
--
Alan Eliasen | "Furious activity is no substitute
eliasen@mindspring.com | for understanding."
http://futureboy.us/ | --H.H. Williams
More information about the Java
mailing list