Miguel de Icaza's web log

« Paolo on Havoc's thoughts | Main | Paolo's follow up »

Java, Gtk and Mono

If you see this from Planet Gnome, you might want to read the rest from the source since it keeps the nice CSS.

Java, Gtk and Mono: (Article Permalink)

So today I figured it would be an interesting excercise to write a small Gtk# application with Java. To do this, I used IKVM the Java VM implementation that runs on top of .NET and Mono.

There are two possible ways of using IKVM: one is to use it as a Just-in-Time compiler which translates the Java bytecodes into .NET Intermediate Language as it goes. But this means that at runtime you are compiling things twice: the Java-to-CIL JIT and the CIL-to-Native JIT.

Gtk# is really a bad name. Because Gtk# is not limited to C#, any programming language in the .NET framework can use it today and because it covers more than only the Gtk API, it covers various other components of the GNOME Development Platform.

Getting Started

First, you need to get your hands on Mono and Gtk#, you can get these from Mono Download page and Gtk# from their sourceforge page, or if you are lazy like I am, you use the packages on Red Carpet.

The next step is to download IKVM.

Exposing .NET Libraries to Java

Now, Gtk# is a .NET assembly (this is the ECMA lingo for "library"), and Java does not know anything about this. It is necessary first to generate some stubs for these classes to let the Java compiler knows about the types defined in the C# world. This is done using the netexp.exe program from IKVM, like this:


    $ mono netexp.exe /mono/lib/mscorlib.dll
    $ mono netexp.exe /mono/lib/gtk-sharp.dll
    $ mono netexp.exe /mono/lib/glib-sharp.dll
    $ mono netexp.exe /mono/lib/atk-sharp.dll

The above commands basically "imports" all of the types and their definitions into something suitable for Java to consume, the result is:


    $ ls *.jar
    atk-sharp.jar  glib-sharp.jar  gtk-sharp.jar  mscorlib.jar

The netexp.exe program will import all of the types into the "cli" namespace. So if you had a class called "Gtk.Window", it will be exposed to Java as "cli.Gtk.Window".

Compiling our program

So I begun with a small Java program, I had to Google for Hello World, since I did not remember much of Java, and I have to say, I am still not comfortable with the classpath thing. Anyways here is my sample little program:

import cli.Gtk.*;
public class Demo {
	public static void main(String[] args) {
		Application.Init ();
		Application.Run ();
	}
}

To compile the above program type:


    $ javac -classpath gtk-sharp.jar Demo.java

This produces a Demo.class file that contains the Java bytecodes. The -classpath file instructs the Java compiler to find the type definitions on the gtk-sharp.jar file that we had previously produced with netexp.exe.

Running our Java code in Mono

Now, it is not possible to run this directly in Java, since the jar files produced by netexp.exe are only stubs, so we will need to run this in the Mono world using IKVM in JIT mode:


    $ mono ikvm.exe -classpath .:gtk-sharp.jar Demo

The above just sits there waiting for events, so feel free to kill that. We will now add some meat to the program, this is a slightly more interesting sample:


import cli.Gtk.*;
import cli.GLib.*;

public class Demo {
	public static void main(String[] args) {
		Application.Init ();
		Window w = new Window ("Hello Mono with Java#");
		Button b = new Button ("Click me");
		w.Add (b);
		w.ShowAll ();
		Application.Run ();
	}
}

To compile, you will need to reference the libraries we created before:


    $ javac -classpath 'gtk-sharp.jar:glib-sharp.jar:atk-sharp.jar:
    mscorlib.jar:.' Demo.java

This will produce Demo.class, now run it:


    $ mono ikvm.exe -classpath .:gtk-sharp.jar Demo

The result is shown here:

The above is basically translating Demo.class from JVM bytecodes to ECMA CIL, then the Mono JIT translates that into native x86 code. The next step is to precompile the Java code directly into .NET code, which will skip the double JIT process:


    $ mono ikvmc.exe -reference:`pwd`/classpath.dll Demo.class \
      gtk-sharp.jar
    $ ls *exe
    Demo.exe
    $

The above compiled the code directly into a a Mono/.NET executable, to run it, just do:


    $ mono Demo.exe

Compiling Java code to x86 code

But we can go one step further. We can avoid completely the JIT process by precompiling the .exe file which contains instructions in the ECMA Common Intermediate Language into native x86 code using Mono's Ahead-of-Time compiler, to do this, type:


    $ mono --aot Demo.exe
    $ ls Demo.*
    Demo.class  Demo.dll  Demo.exe  Demo.exe.so

The Demo.exe.so contains the native x86 code. Mono still requires the Demo.exe file to be around to extract metadata, but the Just-in-Time compiler will not be used in that case:


    $ mono Demo.exe

Mono detects the shared object file and resolves methods to those contained in the image file. You can see the native code generated by using the objdump command:


    $ objdump -d Demo.exe.so
    ...
    

Caveat: in some versions of IKVM references to System.IntPtr are turned into gnu.classpath.RawData, and your program might not compile in the javac, to fix this problem do:


    $ echo "package gnu.classpath;" > RawData.java
    $ echo "public class RawData {}" >> RawData.java
    $ javac RawData.java
    $ mkdir -p gnu/classpath
    $ mv RawData.class gnu/classpath

How complete is Mono/IKVM?

Mono and IKVM depend on the GNU Classpath, so it is as complete as open source Java, but you get the added advantage of accessing any Mono/.NET libraries as well.

Today Mono/IKVM can run large applications like Eclipse, Jython and JBoss. Screenshot of Eclipse running on Mono.

Patent issues in the software industry

On Software Patents: (Article Permalink)

I was asked to post this on my blog, a copy of a post from the mono mailing list. This is slightly edited from the original:

The fear that people have on Mono's legal issues apply equally as well
to everything else.  Let me explain.

Sun owns various patents on Java, and they might just feel at some
point threatened enough to use them as a weapon against open source. 
In the same way people feel that Microsoft might pull that trigger.

Just to put things into a different perspective: Sun has litigated over
Java in the past (against Microsoft) over a contractual dispute and has
done threatening legal moves against JBoss at some point (which I do
not claim to understand) over bits of J2EE.

If Java on Linux became a threat to Sun, would they use their patents? 
I do not know, and I hope not.  Am only illustrating the point, just
like other people have vehemently illustrated the Microsoft patent risk
before.  

There is nothing in Java that makes it any safer than Mono at this
point.  We do not have any guarantees, any written statements, any
guarantees that Java on Linux will not be sued under certain
conditions.

Microsoft has granted RAND+Royalty Free licenses to any patents they
might own that are required to implement the ECMA 334/335 standards. 
So at least our core VM, classes and compilers are safe from any
litigation from *Microsoft*.  

Now, pay attention to the above, because it is important.

The fact that Microsoft has given access to any patents they might hold
on .NET does not mean that a third party that has a patent that is
required to implement ECMA (or Java) will grant that license.

Why does this matter?  Because we just do not know if someone has a
patent on pieces that Java and .NET implement.  There might very well
be one that we are not aware of.  The patent might remain sleeping for
a few years before someone decides to profit from it.

And the above is important.  It is important because even with a fully
re-engineered virtual machine, runtime system and the rest, we do not
know if you will not be infringing on a Sun, Microsoft or third party
patent.

With the current patent situation, it is probably impossible to ask
small startups or individual developers to do a patent review before
they make decisions on how to implement their software, only very large
companies might afford it, and believe me, even with vast resources,
you might be taken to court by an unknown (Eolas patent for example) or
by a law firm who focuses on purchasing dormant patents and litigate
them.

Nat used to say "If you write a thousand lines of code, you are
violating someone's patent today".  

The picture is not pretty for anyone in the software industry.  

But this is similar to what happens to biology students: on their first
four semesters as they learn about all the dangers, infections, vectors
for infections and bacteria, they stop eating everything, they start
washing their hands with special products, they double clean their
utensils, they wash their fruits ten times a day.

Two years later they are eating food with their bare hands again. 

blog comments powered by Disqus

This is a personal web page. Things said here do not represent the position of my employer.