# Monday, April 23, 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- (source + binaries) and ikvmbin- (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, April 23, 2007 5:14:08 PM (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, April 23, 2007 8:54:34 AM (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, April 23, 2007 7:42:14 AM (W. Europe Daylight Time, UTC+02:00)  #    Comments [5]
# Wednesday, April 11, 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; }
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, April 11, 2007 3:31:01 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [3]
# Monday, April 9, 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");
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, April 9, 2007 11:32:31 AM (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.


  • 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, April 9, 2007 10:19:22 AM (W. Europe Daylight Time, UTC+02:00)  #    Comments [1]
# Monday, March 26, 2007
New Snapshot

The GNU Classpath 0.94 release is due soon (hopefully), but in the mean time here's a new snapshot.


  • Integrated current GNU Classpath cvs version.
  • Fixed VMStackWalker.firstNonNullClassLoader() to handle reflection scenarios (this fixes a problem with serialization where the wrong class loader would be used when deserializing a class that has a custom readObject method.)
  • Added VMFile.setReadable/setWritable/setExecutable/canExecute. Although only setWritable does anything halfway usable (all these methods behave like the JDK on Windows, so only the file's ReadOnly attribute is manipulated).
  • Changed the build process to build IKVM.Runtime.dll in two passes, the first pass is used to compile IKVM.GNU.Classpath.dll against and then in the second pass IKVM.Runtime.dll can statically reference IKVM.GNU.Classpath.dll. This removes the need to use reflection to find IKVM.GNU.Classpath.dll at runtime and thus allows multiple versions of IKVM to co-exist side by side in the same AppDomain now.
  • Added support for stubbing abstract methods that contain unsupported argument types (ByRef and Pointer)
  • Regenerated mscorlib.jar and System.jar
  • Changed RetentionPolicy on .NET custom attribute annotations to RUNTIME, so that ikvmc sees them (fixes a regression).
  • Handled signature clashes in .NET type methods.
  • Made method parameter name handling robust against invalid or incomplete local variables tables.
  • Fixed interface implementation to recurse all the way up.
  • Fixed bytecode metadata table to mark div/rem bytecodes as possibly throwing an exception (this fixes bug 1676377, thanks to Dennis Ushakov for reporting this)
  • Made WinForms/AWT thread into a Background thread, to prevent it from keeping the process alive.
  • Added -time option to ikvmc.
  • Added x64 detection to jvm.dll build script.
  • Fixed several .NET 2.0 "ReflectionOnly" bugs.
  • Implemented java.awt.Desktop peer.
  • Fixed several issues pointed out by FxCop: FileChannelImpl now calls GetLastWin32Error() immediately after the P/Invoke. Runtime.addShutdownHook() now has a LinkDemand for ControlAppDomain (because it exposes the AppDomain.ProcessExit event, which also has this LinkDemand). Ghost types now have an Equals, GetHashCode, == and != method. Comparable.__Helper now has a private constructor and is sealed. Shadow methods in remapped types (that exist to hide the base class methods from Intellisense) now copy any LinkDemands from the methods they hide.

Binaries available here: ikvmbin-0.33.2641.zip

Monday, March 26, 2007 3:01:11 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]
# Sunday, March 25, 2007
Running DOS Games

Since I'm running Vista x64, I can't run DOS apps anymore (since the AMD64 arch doesn't support VM86 when running in 64 bit mode). I can, of course, still run DOS inside the VMWare image of my old machine, but now there something much cooler JPC. An x86 PC emulator written in Java. Naturally, I had to try running it on IKVM:

Lemmings for DOS running on IKVM

The image shows Lemming for DOS running on the JPC x86 emulator running on IKVM.NET running on the x64 CLR.

Unfortunately IKVM's AWT support is not good enough for this app to work, so I had to do some pretty gross app specific hacks to make it "work" (that I obviously won't check in). It's also awfully slow (on JDK 1.6 the game is actually playable, but on IKVM definitely not.)

If any of the other GNU Classpath hackers want to try running JPC. Here's the AppletViewer class I used:

import java.awt.*;

class AppletViewer
  public static void main(String[] args)
    Frame f = new Frame();
    f.setSize(640, 480);
    f.setLayout(new GridLayout(1, 1));
    org.jpc.j2se.JPCApplet applet = new org.jpc.j2se.JPCApplet();

The JPC applet jar can be downloaded here.

Sunday, March 25, 2007 12:41:43 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [2]
# Monday, March 19, 2007
ThinkPad Z61p & Vista x64

About a month ago my new ThinkPad Z61p arrived. It came pre-installed with Windows XP, but I always do a clean install to remove all the junk that comes with a new system (although Lenovo isn't nearly as bad as some OEMs). I decided to be adventurous and install Vista Ultimate x64.

Virtual PC 2007

I copied the harddisk of my old laptop to a VHD file, so that I would be able to use Virtual PC 2007 to run my old configuration. Well that was a big mistake. Virtual PC 2007 is a useless piece of crap. First of all, it had problems with the VHD file because it was bigger than 64GB (which surfaced as "Sector not found" errors in the virtual machine) and after I resolved that by shrinking the disk to 60GB the performance was horrible (it appears they *still* haven't solved the laptop/chipset/keyboard responsiveness issue). After getting fed up with that I switched to VMWare 6.0 beta and I have been very happy with that (I've been a VMWare user since 1.0, but wanted to give Virtual PC 2007 a chance since it's free [as in beer] now.)


The fact that the harddisk was *always* busy drove me crazy (and made things often very slow), so I've disabled the Windows Search indexing service, after doing that and using a 2GB Kingston USB memory key as a ReadyBoost cache performance is acceptable. It's hard to compare with my previous XP system, because I also switched to Office 2007 and Outlook 2007 is a real pig.


The integrated WiFi doesn't work. It looks like the driver works fine (I can see all WiFi networks in the area just fine), but when Vista tries to establish a secure connection, it fails (well, it actually succeeds and then breaks the connection again after a few seconds). All of the built in diagnostics crap is totally useless (as expected). The built-in flash reader also doesn't work (the Lenovo support site doesn't have a driver, but with some Googling I was able to find one, but it was very unstable).


I've switched my main IKVM development environment to Visual Studio 2005 (but will still support .NET 1.1) and when I do my test builds I now build in 64 bit mode. This works surprisingly well and the performance is excellent. I was a bit skeptical about the x64 CLR JIT because of my previous experiences on Windows XP x64 (the performance there basically sucked), but the Vista CLR build (which is a newer build) appears to have fixed that.

As a result of running on .NET 2.0 most of the time now, I've fixed several "ReflectionOny" bugs (when IKVM is built on .NET 2.0 it uses the ReflectionOnly assembly loading context for ikvmc and ikvmstub).

Monday, March 19, 2007 8:52:40 AM (W. Europe Standard Time, UTC+01:00)  #    Comments [1]
# Saturday, March 17, 2007
More Magic

Thanks to Stuart's prodding, the next version of ikvmc will automatically add a System.IDisposable or System.Collections.IEnumerable implementation to any Java classes that implement java.io.Closeable or java.lang.Iterable (respectively).

That means that you can now do this in C#:

java.util.ArrayList list = new java.util.ArrayList();
using (java.io.FileWriter fw = new java.io.FileWriter("test.txt"))
  foreach (string s in list)

Note that the interfaces are only added to the classes (i.e. the java.io.Closeable interface doesn't implement System.IDisposable). From Java this change is mostly invisible, e.g. when you use Java reflection you won't see System.IDisposable on java.io.FileWriter. However, when you use the instanceof operator or do a cast to cli.System.IDisposable, it will succeed. It would be possible to remove this inconsistency, but I don't think that's worth it.

Too Much Magic

Too much of anything is never a good thing, but in the case of adding magic to ikvm, it has always been very difficult to draw the line between just enough and too much. There already is a fair bit a magic in ikvm and I tend to be rather conservative in adding more. The main reason is that magic is almost never "perfect", this means that in most cases it will work as expected, but there are always edge cases where people will be surprised by how things work and that's clearly not good.

Stuart also wants Java's foreach construct to work on .NET types that implement IEnumerable, but to make that work would require turning java.lang.Iterable into a ghost interface and I currently feel that would be in the "too much magic" category, especially considering that ghost interfaces are not very good magic.

Saturday, March 17, 2007 3:05:07 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [0]