# Monday, 19 November 2007
Splitting the Class Library Assembly

In a comment to the previous post Peter asks:

Do you plan to split the classpath assembly into multiple smaller assemblies at some point? The OpenJDK-based one is getting *huge* and when you only use a small subset of JDK (as I think most people who don't use IKVM as an alternative to JRE, but use it so that they can embed Java code in .NET app, do), it's pretty high overhead...

Cyprien Noel posted a feature request:

Would it be possible to split the dll with the jvm classes in 2 or more
parts ? E.g. a basic dll with java.lang, util, math, io, net, text, and
another dll with the other features. Thanks

Others have asked similar things. I'm very sympathetic to this request, because the bloat of the Java API has annoyed me ever since JDK 1.2.

Unfortunately this is a very hard problem without upstream support. Since Sun has never had any incentive to reduce dependencies inside the class library (because up until now it has always shipped as a single file), there is a pretty tight coupling between many packages in the Java class library. For example, just the static dependencies of java.lang.Object amount to 1893 classes in the IKVM 0.36 release codebase. Note that these are just the static dependencies and this set of classes won't even allow you to run "Hello World". However, adding a few more classes (to a total of 2676) gives a, what appears to be, workable subset and yields an assembly of approx. 5.5MB.

That looks like a great start, doesn't it? However, the problem is that it isn't at all clear what this assembly supports. For example, it supports the http protocol, but not the https protocol. Simply adding the https protocol handler drags in an additional 1895 classes!

Suppose I put the https support in a separate assembly and when you test your application you only test with http URLs so everything works with just the core assembly and you decide to ship only the core assembly. Now a user of your code tries an https URL and it doesn't work. This may seem like an obvious thing, but there are probably other scenarios that aren't as obvious.

The key point here is that I have no idea of most of the inner workings of the class library, so it would be difficult (or extremely time consuming) for me to figure out the best way to split the classes and to give any guidance as to when you'd need to ship what assembly.

Why I'm Probably Still Going To Do It

There is another argument for splitting the class library assembly: Performance. For example, depending on the scenario, having several smaller assemblies that are demand loaded may be more efficient than a single huge assembly. Especially because the assemblies are strong named and the CLR verifies the assembly hash when it loads the assembly (if the assembly isn't in the GAC).


As is usually the answer: I don't know. It'll be done when it's done. In the meantime you can always download the sources and build your own subset class library assembly :-)

Monday, 19 November 2007 08:51:30 (W. Europe Standard Time, UTC+01:00)  #    Comments [4]
# Thursday, 15 November 2007
0.36 Release Plan

Ben asked about the 0.36 release yesterday. Here's the situation: There will be at least one more 0.36 release candidate that includes the new custom assembly class loader support and the fixes I've done since rc5. I'm currently waiting for some test results from the sponsor of the 0.36 release, to make sure that everything that needs to be fixed is fixed before release.

Thursday, 15 November 2007 08:12:29 (W. Europe Standard Time, UTC+01:00)  #    Comments [2]
# Tuesday, 13 November 2007
Development Snapshot Update

Three more fixes and a complete set of binaries this time.


  • Fix to make sure that a ghost interface method call always goes thru the target reference wrapping path. (Calling java.lang.CharSequence methods through an interface that extends java.lang.CharSequence would generate incorrect code.)
  • Fixed ghost interface array casting to generate verifiable code.
  • Fixed FileChannelImpl to close the FileDescriptor after releasing the file locks.

Binaries available here: ikvmbin-0.37.2873.zip.

Update: Fixed the link.

Tuesday, 13 November 2007 08:19:28 (W. Europe Standard Time, UTC+01:00)  #    Comments [3]
# Friday, 02 November 2007
Development Snapshot Update

Two fixes. This time I'm only releasing an updated version of IKVM.Runtime.dll as that is all that changed.


  • AppDomainAssemblyClassLoader now skips AssemblyBuilders. Previous version would cause problems if any dynamically generated assemblies were present in the AppDomain.
  • Fixed a bug in the DynamicMethod based reflection implementation that caused a NullPointerException when generating the setter for a final instance field for code that isn't compiled with -strictfinalfieldsemantics.

Update available here: ikvmbin-upd-0.37.2862.zip.

Friday, 02 November 2007 08:02:15 (W. Europe Standard Time, UTC+01:00)  #    Comments [0]
# Friday, 26 October 2007
Writing a Custom Assembly Class Loader

A new development snapshot. It's now possible to write your own custom assembly class loader. This is the recommended pattern:

class MyCustomClassLoader extends ClassLoader
  MyCustomClassLoader(cli.System.Reflection.Assembly asm)
    super(new ikvm.runtime.AssemblyClassLoader(asm));

  protected Class findClass(String name)
    // TODO: forward call to other class loader or load class and call defineClass()

  protected URL findResource(String name)
    // TODO: forward call to other class loader or find resource somewhere

  protected Enumeration findResources(String name)
    // TODO: forward call to other class loader or find resources somewhere

If you delegate to other class loaders, you should be careful to avoid loops in the delegation path. If you want to change the resource loading delegation order, you can override getResource[s]() instead of findResource[s]() relatively safely, but if you want to change the delegation order for classes you need to be more careful, because you cannot replace any classes that are defined in the assembly.

Of course, you can also reuse existing class loader classes. Here's an example with URLClassLoader:

class MyCustomClassLoader extends java.net.URLClassLoader
  MyCustomClassLoader(cli.System.Reflection.Assembly asm)
    super(new java.net.URL[0], new ikvm.runtime.AssemblyClassLoader(asm));
    // see below why calling addURL() is safer than passing it to the super constructor
    addURL(new java.net.URL("..."));

Note that custom assembly class loader classes and their single argument Assembly constructor must be accessible from the assembly that they are applied to.

Delegation Magic

The ikvm.runtime.AssemblyClassLoader instance that is passed in as the parent class loader is a bit funny. It supports loading classes and resources from the assembly, but it effectively does this by magically delegating back to the custom class loader (without actually calling it, otherwise you'd get infinite recursion.) This means that classes from the assembly can be loaded via the parent class loader, but they report the custom class loader instance as their class loader.

Construction Magic

The custom assembly class loader is constructed when someone calls getClassLoader() on a class defined in that assembly for the first time, but what should getClassLoader() return while the custom class loader is being constructed? For consistencies sake, I've decided to apply some magic here and to make it return the object that is currently being constructed. This implies that you should call the base class constructor ASAP, because as long as you haven't done this the ClassLoader instance is in an unitialized state. After calling the base class constructor you can do additional work to configure your custom class loader, but you should take into account that while you are setting up your instance data, if you do anything that causes a class or resource to be loaded via your class loader, that your methods may run while initialization has not yet been completed. Note that this can only happen for the initiating thread. All other threads that call getClassLoader() will be blocked while the constructor is runnning. If the constructor throws an exception, the initiating call to getClassLoader() will see the exception, but all other calls will return the partially initialized class loader object.

Too Much Magic?

I certainly hope not, but I have to admit this is a scary feature. I recommend only writing your own custom assembly class loader if you really understand Java class loaders and there is no alternative.

Finally, please do send me feedback on this feature (even if it's a simple "I like it" or "It sucks"). I plan on backporting this to the 0.36 release, so it's important to get this right.


  • More changes to keep up the pretense that an AssemblyClassLoader has already loaded all classes in the assembly.
  • Made AssemblyClassLoader public and moved it to ikvm.runtime package.
  • Allow non-public custom assembly class loaders (if they are defined in the same assembly).
  • Fixed ClassLoader.getSystemClassLoader() to return the custom assembly class loader for the main executable, if one is defined, even if the java.class.path or java.ext.dirs system property is set.
  • Restructured AssemblyClassLoader.GetProtectionDomain() to avoid calling any code while holding the lock.

Binaries available here: ikvmbin-0.37.2855.zip.

Friday, 26 October 2007 11:25:23 (W. Europe Daylight Time, UTC+02:00)  #    Comments [4]
# Monday, 22 October 2007
New Development Snapshot

I've made a bunch of changes to support custom assembly class loaders. This should finally solve some of the issues caused by the new class loader architecture. Eventually it will be possible to write your own assembly class loader (hence the name custom assembly class loaders), but currently only the two provided ones are supported: ikvm.runtime.AppDomainAssemblyClassLoader and ikvm.runtime.ClassPathAssemblyClassLoader.


This approximates the pre-0.32 behavior by searching all currently loaded assemblies (after looking in the assembly itself and the assemblies it references).


This class loader supports dynamically loading classes and resources from the CLASSPATH (or java.class.path system property). It too first searches the assembly itself and any assemblies it references. This class loader makes the most sense as a replacement for the assembly class loader of the main executable, that way it will also be the system class loader. Note that if multiple assemblies use this class loader, they each will have a separate class loader instance that loads different classes (even though they may be based on the same class files).

How to Use

There is a new ikvmc option to specify a custom assembly class loader:

ikvmc -classloader:ikvm.runtime.AppDomainAssemblyClassLoader example.jar

For non-Java code you can apply a custom attribute to your code:

using System;

[assembly: IKVM.Attributes.CustomAssemblyClassLoader(typeof(ikvm.runtime.ClassPathAssemblyClassLoader))]

class SimpleJavaRunner
  public static void Main(string[] args)
    string[] newArgs = new string[args.Length - 1];
    Array.Copy(args, 1, newArgs, 0, newArgs.Length);
      .getMethod("main", typeof(string[]))
      .invoke(null, new object[] { newArgs });

You can also specify them in the app.config file, this overrides the above methods:

<?xml version="1.0" encoding="utf-8" ?>
    <add key="ikvm-classloader:MyExampleAssembly" value="ikvm.runtime.AppDomainAssemblyClassLoader, IKVM.OpenJDK.ClassLibrary, Version=, Culture=neutral, PublicKeyToken=null" />

Here the key is ikvm-classloader: followed by the simple name of the assembly. The value must be the assembly qualified type name of the custom assembly class loader type.

As always, feedback is appreciated.


  • Implemented Custom Assembly Class Loaders.
  • Fixed URL.equals() for "ikvmres:" urls.
  • Fixed findResources() bug that caused resources in core assembly to show up twice if a .NET assembly explicitly referenced the core assembly.
  • Added check to prevent defineClass() on an assembly class loader from defining a class that already exists in the assembly.
  • Fixed Class.getModifiers() to mask out ACC_SUPER bit.

Binaries available here: ikvmbin-0.37.2851.zip.

Monday, 22 October 2007 15:22:38 (W. Europe Daylight Time, UTC+02:00)  #    Comments [1]
# Monday, 15 October 2007
Mono Summit 2007

I'll be at the Mono Summit 2007.

Monday, 15 October 2007 11:59:24 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]
# Friday, 12 October 2007
IKVM 0.36 rc5

Yet another release candidate and possibly not even the last one (more on that next week).


  • Fixed reflection regression introduced in rc4.
  • Added workaround for .NET 3.5 beta breaking change.
  • Added support for another binary compatibility issue (public classes nested in non-public classes).
  • Added workaround for another .NET 2.0 x64 JIT bug.

Binaries available here: ikvmbin-

Sources (+ binaries): ikvm-

External sources (haven't changed since rc1): classpath-0.95-stripped.zip, openjdk-b13-stripped.zip

Friday, 12 October 2007 18:28:39 (W. Europe Daylight Time, UTC+02:00)  #    Comments [3]
# Monday, 01 October 2007
IKVM 0.36 rc4

External forces inspired me (read: I was paid) to make another release candidate.

Reflection on .NET is very slow compared with Java and because IKVM reflection was built on top of .NET reflection, it too was very slow. I rewrote the lower levels of reflection to take advantage of DynamicMethod when running .NET 2.0. This allows the slow .NET reflection to be bypassed and optimized accessor methods to be generated dynamically. I also rewrote the part of serialization that uses reflection to get and set the field values to generate custom dynamic methods for the serialization process. Serialization is now up to 20x faster.

Unfortunately I had to disable the use of DynamicMethod when running on Mono, because testing revealed that Mono 1.2.5's implementation of DynamicMethod is still too buggy.

A remaining caveat wrt reflection performance is that you need to call setAccessible(true) to get the best performance when running on IKVM, because stack walking (which is needed to do the required access checks when you access a non-public member) is still very slow compared with Java.


  • Improved serialization and reflection performance when running on .NET 2.0.

Binaries available here: ikvmbin-

Sources (+ binaries): ikvm-

External sources (haven't changed since rc1): classpath-0.95-stripped.zip, openjdk-b13-stripped.zip

Monday, 01 October 2007 15:31:54 (W. Europe Daylight Time, UTC+02:00)  #    Comments [1]
# Thursday, 20 September 2007
IKVM 0.36 rc3

This is probably the last release candiate before the official 0.36 release.


  • Fixed non-blocking nio socket send of zero bytes to not return -1.
  • Fixed nio Selector.wakeup() race condition.
  • Added checks for code that uses reflection to call ClassLoader.defineClass() on the assembly class loader for ikvmc compiled classes to throw IllegalAccessError when the class tries to extend a non-public base class (instead of dying with a Critical Failure).
  • Fixed bug in the handling of Java annotations applied in .NET code (via the corresponding ikvmc generated attributes).
  • Significantly improved performance of Class.getModifiers().

Binaries available here: ikvmbin-

Sources (+ binaries): ikvm-

External sources (haven't changed since rc1): classpath-0.95-stripped.zip, openjdk-b13-stripped.zip

Thursday, 20 September 2007 15:55:12 (W. Europe Daylight Time, UTC+02:00)  #    Comments [1]