Hi all,
Sometimes we can use some moral support. So let me share the following
with you all. Normally we are a bit hesitant to recommend people to
just switch since we cannot guarantee that everything just works.
But we are getting better and better. The following email was just sent
to the i2p mailinglist. i2p is an anonymous network (both message and
stream based support). See for more information http://i2p.net/
There were some small bugs (Calendar seems difficult to get all the
corner cases right) and two performance issues (the SecureRandom one
looks nasty, but I know Andrew is looking at the memory use of gcj
native compiled applications already). All in all the transition seemed
to have gone smoothly and as jrandom said:
In any case, this is quite kickass, as it means we'll be able to
both integrate more cleanly with other languages AND ship
whereever
GCJ ships (DFSG friendly!) Thanks go to the GCJ and GNU
Classpath
folks for their hard work!
Go team!
Mark
---BeginMessage---
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1
Thanks to mjw's prodding, I pulled the latest (4.0.2) gcj last night
and tried my hand at getting I2P up and running under it. End
result is that overnight, I've had my test network pushing gigs upon
gigs of data with half of the network running under sun's JVM, and
the other half GCJ'ed :)
There were three issues of varying degrees of complexity to get
there though:
* 1) Calendar problems
The first is a bug in GCJ (or maybe GNU Classpath, haven't tested
on Jam or Kaffe yet) - when working with a java.util.Calendar, not
all of the fields were being set correctly when they should be:
import java.util.*;
public class t {
public static void main(String args[]) {
Calendar cal = new GregorianCalendar();
cal.setTime(new Date());
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
long midnight = cal.getTimeInMillis();
System.out.println(Midnight: + midnight);
cal = new GregorianCalendar();
cal.setTime(new Date());
// workaround for fields not set
cal.set(Calendar.YEAR, cal.get(Calendar.YEAR));
cal.set(Calendar.DAY_OF_YEAR, cal.get(Calendar.DAY_OF_YEAR));
// continue as normal
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
midnight = cal.getTimeInMillis();
System.out.println(Workaround: + midnight);
}
}
Both JVMs (Sun and GCJ) display the workaround properly, and Sun's
displays the original Midnight: properly, but GCJ's
cal.getTimeInMillis() returns 0 (the YEAR and DAY_OF_YEAR fields
are not properly computed).
There are a few places in I2P's code where we use Calendar in this
sort of way, but the latest I2P CVS includes workarounds for these
issues.
* 2) xerces problems
The xerces we ship with won't compile cleanly under GCJ - it
complains about missing references to some sun.* functions. We
aren't using the latest xerces though, and since mjw told me that
it should work, I'll grab the latest and give it a go, upgrading
our CVS xercesImpl.jar if it works (and causes no regressions).
In any case, xerces isn't technically necessary for I2P operation
- its only used by Jetty for the router console (a really, really
useful application, but not technically necessary).
* 3) prng problems
We gobble random bits like crazy. To get a functional system, I
had to disable our PRNG pool (which pulls data out of
java.security.SecureRandom) and enable the weak PRNG (which pulls
data out of java.util.Random). This is not necessarily
entirely GCJ's fault, but more of an issue with the OS which GCJ
doesn't hide.
Shipping with the weak PRNG wouldn't be prudent though, so we'll
need to go back and revive the Fortuna integration effort before
shipping GCJ'ed routers.
Overall, this is fantastic news - I'm glad mjw convinced me to give
it another shot. The I2P SDK, the streaming library, and the client
apps all build fine under GCJ, completely compatible with ones
running on Sun's or IBM's JVM. I've had a GCJ'ed version of
i2psnark running overnight, doing swarming file transfer with normal
i2p-bt and azneti2p peers without problem.
One of the really interesting things here is how this affects SAM -
with the I2P SDK and streaming libraries built into libi2p.so (or
even libi2p.a), there is no reason why Python/C/C++ apps couldn't
link against those objects and use
net::i2p::client::streaming::I2PSocket directly! If someone wants
to explore this avenue, it does sound very promising.
A side note regarding GCJ. I realize everyone always complains that
Java uses up tons of memory, and if only we had native apps it'd
magically allocate out of thin air ;) Unfortunately, while the
overnight router test