# Wednesday, 18 May 2011
Implementation Dependencies

Field Ordering

A new feature in today's snapshot is that java.lang.Class.getDeclaredFields() now returns the fields in class declaration order for ikvmc compiled code (dynamically compiled code always did this).

This is not required by the specification, but recently after debugging a complex piece of code that failed when compiled with ikvmc because of a field ordering dependency I did some more thinking and came up with a way to cheaply retain the field ordering.

IKVM.Reflection

Like Java reflection, System.Reflection makes no promises about ordering, so how do you retain the ordering without adding additional bookkeeping overhead? The key lies in IKVM.Reflection, since ikvmc now uses IKVM.Reflection to emit the metadata I know how to make sure that fields are emitted in a particular order and that this gives them increasing metadata tokens.

So all I had to do is make a minor modification to ikvmc to define the fields in the same order as they are defined in the class file and in the runtime reflection code sort the FieldInfo array returned by Type.GetFields() by metadata token.

Annotations by Proxy

The JDK implements annotations by using java.lang.reflect.Proxy to implement the annotation interface. This is an implementation decision and not promised by the spec anywhere, but predictably there is also code that (for no good reason) assumes that annotations are always implemented by java.lang.reflect.Proxy.

This code failed on ikvmc compiled code, because there I generated .NET custom attributes that implement the annotation interface and simply returned the custom attribute object.

So I've changed the annotation reflection code to now return a java.lang.reflect.Proxy as well (for compatibility, the custom attribute annotations still implement the annotation interface).

Conclusion

You can write whatever you want in the specification, but when an ecosystem is dominated by one implementation, people are going to write against the implementation, not the specification.

This is not just annoying for alternative implementations, but the dominant implementation also suffers, because in subsequent versions you have far less freedom in evolving your implementation.

Wednesday, 18 May 2011 08:23:51 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]
New Development Snapshot

Since it has been a while, time for a new development snapshot.

Changes:

  • Expose annotations on statically compiled code as java.lang.reflect.Proxy instead of the custom attribute object, to deal with broken code that assumes annotations are always implemented with Proxy. Fix for #3254823.
  • Added delegate conversion for java.lang.reflect.InvocationHandler to ikvm.runtime.Delegates.
  • Changed build to specify "-cp dummy" for javac compile to avoid accidentally picking up classes on the CLASSPATH.
  • Added experimental (i.e. not yet finished) -proxy: option to ikvmc to pre-generate proxy class.
  • Added method prologue support to remap file.
  • Updated AtomicInteger, AtomicIntegerArray, AtomicLonger, AtomicLongerArray to use .NET 2.0 interlocked operations.
  • Added stind_i8 opcode to remap file.
  • Changed build and JNI code to use different names for the Windows x86 and x64 versions of the native dll.
  • Added missing lib/*.properties files (in particular lib/calendars.properties which caused java.util.JapaneseImperialCalendar to fail).
  • Retain reflection field ordering for ikvmc compiled code (not required by spec, but to improve compatibility with broken code).
  • AWT: Fixed a StringIndexOutOfBoundsException if RTL and LTR text are used in one string.
  • AWT: Added emulation for fixed metrics to make drawString and stringWidth compatible.
  • AWT: Added workaround for bug in OpenJDK 6 on Windows. The result is that the needed width for painting of labels and buttons can be 1 pixel larger as the prefered size. The result was labels with "...".
  • IKVM.Reflection: Fixed TypeBuilder.DefineNestedType() to accept a null reference for the interfaces parameter.

Binaries available here: ikvmbin-0.47.4154.zip

Wednesday, 18 May 2011 07:57:20 (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]