# Sunday, 29 April 2007
IKVM 0.34 rc3

While working on NIO pipe support in the development branch, I found a few socket bugs and I decided to back port them to the 0.34 release. I've also back ported the NIO pipe support itself, since that's a low risk change.

Changes since rc2:

  • Implemented NIO pipe support.
  • Added support for socket connect with timeout.
  • Fixed Socket.bind() to set local port after binding.
  • Fixed SocketChannel.read() to return -1 if other side closed the socket.
  • Fixed ServerSocketChannel.accept() to properly set the state in the returned socket, to fix the socket from breaking if you called certain Socket methods on the SocketChannel.socket(). This was a regression introduced during the 0.33 development.

Files are available here: ikvm-0.34.0.2.zip (source + binaries) and ikvmbin-0.34.0.2.zip (binaries).

Sunday, 29 April 2007 11:01:44 (W. Europe Daylight Time, UTC+02:00)  #    Comments [2]
# Wednesday, 25 April 2007
IKVM 0.34 rc2

A new release candidate that fixes a regression in String.lastIndexOf(String,int) that I introduced in rc1.

Files are available here: ikvm-0.34.0.1.zip (source + binaries) and ikvmbin-0.34.0.1.zip (binaries).

Also a clarification: As of this release there is no longer a separate “generics” build, because the 1.5 specific stuff has been merged into the GNU Classpath main release.

Wednesday, 25 April 2007 05:52:45 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]
# Monday, 23 April 2007
IKVM 0.34 rc1

GNU Classpath 0.95 has been released! Here's the corresponding IKVM release candidate. I've updated the Japi status page.

Changes since previous snapshot:

  • Integrated GNU Classpath 0.95 release.
  • Fixed ByteBuffer.allocateDirect() to zero initialize the memory it allocated.
  • Fixed various String methods (indexOf, lastIndexOf, startsWith, endsWith, contains, replace) to use ordinal semantics instead of culture dependent word matching. Thanks to Louis Boydstun for tracking this bug down.
  • Fixed potential deadlock when a dying thread is interrupted.

Files are available here: ikvm-0.34.0.0.zip (source + binaries) and ikvmbin-0.34.0.0.zip (binaries).

As usual these are the strong named binaries and if no major issues are found these files will be released and placed on the SourceForge download page.

Monday, 23 April 2007 17:14:08 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]
JCK Certification

Dan Diephouse wrote in the comments to the previous entry:

Thats some serious comment spam thwarter - I had to look up the answer! Might I suggest Askimet? It rocks.

Yeah, sorry about that. That was mainly driven by ease of implementation. The fixed question was very easy to add in the aspx page without having to do any thinking on my part. The most amazing part is that a spammer actually managed to get through a couple of weeks ago.

Anyway, was wondering, do you think IKVM could ever become a certified java run time? (provided Sun made the JCK available under a reasonable license)

Funny you should ask, because I was thinking about blogging about this question yesterday (inspired by the Apache open letter and Mark Wielaard's and Dalibor Topic's responses).

The short answer is that it's not my goal for IKVM to be a certified Java runtime. I do not have access to the JCK, but it is my understanding that adding extra functionality is not allowed. Since IKVM runs on .NET it makes sense to expose .NET functionality (like for example delegates and P/Invoke). Remember that when Microsoft added delegates and J/Direct (which is the predecessor to P/Invoke) to its JVM they got sued by Sun for violating their license agreement.

There are also other issues that make a fully compliant version of IKVM only of theoretical interest. The floating point performance would be pretty bad, for example. Currently, the floating point support uses the native .NET floating point operations, but those are too relaxed for the JVM specification (mostly because they use too much precision). Another example: If you wanted static initializers to work according to the JVM spec (i.e. deadlock in certain scenarios), that would make them less efficient and would hinder interop with .NET code. One more: Because CharSequence is a ghost interface, when you do new CharSequence[] you really get an Object[], again it's possible to hide this from Java code, but it would make all object array access very slow.

Finally, there is one thing that I really don't know how to implement (in the current architecture). In Java it is possible for JNI code to allocate a string object and then later on call the constructor on it (or even to call the constructor twice), because .NET strings are variable size objects and require that the contents be specified at allocation time this is impossible to implement on IKVM.

Monday, 23 April 2007 08:54:34 (W. Europe Daylight Time, UTC+02:00)  #    Comments [4]
Running Application Test Suites

Last week an anonymous person filed three bugs (1701353, 1701738 and 1701756). The first one was a URI bug that was already fixed in GNU Classpath, but the other two were more interesting because they included references to Eclipse projects that include JUnit test suites that reported some failures.

Now this is not always the case, but running the test suites for these two projects was a joy and resulted in several bugs filed/fixed:

Random MTJ test failures GNU Classpath java.util.Arrays.sort() bug
JRuby test_bignum failure GNU Classpath java.math.BigInteger.mod() bug
JRuby test_zlib failure GNU Classpath java.util.zip.GZIPInputStream constructor bug
Random JRuby test_thread_group hang        IKVM.NET thread termination deadlock bug


The reason that the MTJ tests failed in a random way was because the tests are non-deterministic. They generate random sized matrices, so the sort bug wouldn't always result in an incorrect sorting of the array indices.

Unfortunately I had to close 1701738 as Wont Fix. The JRuby test_array test intentionally causes a stack overflow and then JRuby expects to recover from that by catch StackOverflowError, but it's not possible for IKVM to reliably support catching a System.StackOverflowException and then mapping it to java.lang.StackOverflowError. The mapping exists, but if the exception is caught while there is not enough stack space for the mapping code to run, the CLR terminates the application.

The are two more JRuby tests that fail: test_io and test_pipe. These tests fail due to the fact that I haven't yet implemented NIO pipes. This is the first time ever that I've seen code "use" NIO pipes, but since it's only a test case I'm still not very motivated to implement them (but patches are welcome, as are applications that use NIO pipes).

If anyone has any other suggestions for test suites (that are easy to run like these), I'd love to hear them.

Monday, 23 April 2007 07:42:14 (W. Europe Daylight Time, UTC+02:00)  #    Comments [5]
# Wednesday, 11 April 2007
Detecting .NET 2.0 x64

In the category .NET trivia. I found a weird difference between .NET 2.0 x86 and x64. This code detects that it runs on x64 (at least the .NET 2.0 build included with Vista x64):

WeakReference r = new WeakReference(null);
try { throw new Exception(); }
catch (Exception x) { r.Target = x; }
GC.Collect();
if (r.Target != null)
  Console.WriteLine("Running on x64");

It appears that the last thrown exception is stored in a global (or rather probably thread local) variable and hence not garbage collectable until the next exception is thrown...

Update: I thought this was obvious, but since two commenters have felt the need to point out that you shouldn't use this in production, I'll say it explicitly:I was just pointing out some obscure implementation difference (arguably a bug), do not use this code in production.

Wednesday, 11 April 2007 15:31:01 (W. Europe Daylight Time, UTC+02:00)  #    Comments [3]
# Monday, 09 April 2007
Memory Mapped Files

What happens when you get a read error while accessing a memory mapped file? Let's try it:

RandomAccessFile raf = new RandomAccessFile("\\\\server\\share\\filename", "r");
FileChannel channel = raf.getChannel();
MappedByteBuffer map = channel.map(FileChannel.MapMode.READ_ONLY, 0, 5 * 1024 * 1024);
map.get(10 * 1024);
System.out.println("read byte at 10K -- waiting");
Thread.sleep(5000);
map.get(500 * 1024);
System.out.println("read byte at 500K");

Running this on JDK 1.6 (x64) and removing the network cable during the sleep will result in an Internal Error in the VM. Not exactly what I had hoped for.

Interestingly, on IKVM doing the same results in a cli.System.Runtime.InteropServices.SEHException being thrown.

Monday, 09 April 2007 11:32:31 (W. Europe Daylight Time, UTC+02:00)  #    Comments [1]
New Snapshot

The GNU Classpath 0.95 release branch has been created (0.94 was skipped), so it shouldn't be long now before I will release IKVM 0.34, but before that here's a final snapshot containing everything that will be in 0.34.

Changes:

  • Integrated current GNU Classpath cvs version.
  • .NET "generic class loaders" now return something (mildly) sensible when toString() is called on them.
  • ikvmc no longer warns about generic stubs.
  • ikvmstub now has WHIDBEY conditional code to properly determine if a class is a generic type instance (instead of the name based hack).
  • Fixed .NET generic type name mangling bug (nested generic types were double encoded).
  • Added support for loading .NET generic type stubs.
  • Fixed several .NET generic type loading bugs.
  • Fixed ikvm.runtime.Util.getInstanceTypeFromClass() to return null instead of throw an exception when it is called on a "dynamic only" class.
  • Changed ikvmstub to use java.util.zip instead of SharpZipLib.
  • Fixed index/length overflow detection in arraycopy_primitive_n methods.
  • Fixed JNI init args and thread attach string conversions.
  • Added workaround for .NET bug that caused OverflowException when compiling a class with an initialized final instance field of type char with a value > 32K.

Binaries available here: ikvmbin-0.33.2655.zip

Monday, 09 April 2007 10:19:22 (W. Europe Daylight Time, UTC+02:00)  #    Comments [1]