Andy Malakov software blog

Thursday, June 12, 2008

Ant task for IKVMC

Submitted Ant task for IKVMC - ant-ikvmc. I found multiple FileSet elements in Ant more convenient in defining source classes than -recurse:mask command line argument provided by IKVMC.

Example of task:

<ikvmc target="library" out="${dotnet.out}/uhfclient.dll" home="${ikvm.home}" version="1.0.0.0" debug="true"  verbose="true">
<reference path="${dotnet.out}/uhfc-3rd-party.dll"/>
<fileset dir="${classes}" includes="${uhfdll.resources}">
<exclude name="**/*.vpp"/>
<exclude name="**/*.txt"/>
</fileset>
<fileset dir="${jars}">
<include name="**/*.jar"/>
<exclude name="foo.jar"/>
</fileset>
</ikvmc>

Bonus: Java doclet that generates IKVMC mapping file. Among other things mapping file can specify parameter names in methods and constructors translated by IKVMC. Since Java parameter names are not available from Java class files, IKVMC needs this hint to preserve original Java names. This is handy if you generate API libraries that will be used by .NET developers.

Here is an example of javadoc task to generate IKVM mapping file for selected packages:

 <javadoc sourcepath="${src}" classpath="${javac.classpath}" defaultexcludes="yes">
   <doclet name="deltix.tools.ikvmc.ant.IkvmcMapDoclet" path="${classes}">
     <param name="-out" value="${mapfile}"/>
   </doclet>
   <package name="com.acme.api"/>
   <package name="com.acme.util"/>
 </javadoc>

IKVM for Java - .NET interoperability

Front-end to our Java-based server is written on C#/.NET. Interoperability is achieved using XML/WS-based server API (as well as some custom binary format for high volume data responses). Typical architecture. Well, this is going to change now, after we discovered IKVM project. IKVM translates Java byte code into MSIL.

The lack of Microsoft Java implementation for .NET platform has obvious commercial reason. But what cannot be done by the largest software company was done by single developer - Jeroen Frijters (the man behind IKVM). Amazing.

JAXB 2.1 is now in Java 6 (almost)

Looks like Sun folks silently updated Java 6 to use JAXB 2.1 API. The fact that Java 6 was shipped with old version of JAXB used to be a lot of pain. Hopefully we don't need to mess with endorsed directory workaround anymore.


I run a diff and it turns out that JAXB API shipped with JDK 1.6 is almost identical to 2.1. It has only one significant difference from 2.1.6: Class javax.xml.bind.ContextFinder refers to a different location of Context Factory. In com.sun.xml.internal.bind.* became com.sun.xml.bind.*



Bottom line: if you want to use JAXB 2.1 with 1.6, simply add JAXB implementation in your classpath. No need to use Java endorsed mechanism anymore.



P.S. Also the following frequent error is now a history: "java.lang.LinkageError: JAXB 2.0 API is being loaded from the bootstrap classloader, but this RI requires 2.1". If you still see it with JAXB 2.1 in classpath simply update your Java 6 to the latest version (I tested it with 1.6.0_04-b12+ which was released in Spring 2008).

Monday, June 2, 2008

JAXB error "java.lang.StackTraceElement does not have a no-arg default constructor"

Our Java-based XML service responds with exceptions in case of errors, so naturally it serializes subclasses of java.lang.Exception to XML.



Unfortunately JAXB 2.1.x fails when someone attempts to marshal a subclass of Exception:java.lang.StackTraceElement does not have a no-arg default constructor. This can be fixed using mechanism of JAXB Introductions. I just posted a fix here.