Saturday the 19th September 2015
Hi my name is Joakim Nordström, and I'm going to talk about Java for Amiga, which is my night time project.
At daytime I'm a system developer at Telia here in Uppsala
and at night time I'm trying to get java to work on the Amiga
The project I'm working is called JAmiga, and I have continued on an open source project from 2003-2005
It was started by two Germans, Peter Werno and Andre Dörffler.
They started creating Java for Amiga.
and released a version in 2005, and then nothing much happened until around 2009 when I began looking at it.
At that time they supported parts of Java 1.4.
If you know something about Java, you'll get something from this, and if you know nothing about Java, I hope you'll also get something out of this.
So hopefully everyone will be happy at the end, or everyone will be confused by my ramblings.
The target architecture is Amiga, and I'm working at the next generation Amiga.
So it isn't the classic Amiga as seen on the first slide I'm focusing, but rather the next generation Amigas.
And, believe it or not, Amiga still selling some sort of computers, and then one I have is this with a Power PC processor.
And if I'm not mistaken, this is the same processor Mac should've used, if they didn't switch to Intel.
The operating system i s Amiga OS 4.1, the latest release.
Audience question: can you run old Amiga applications on this new computer?
Yes, yes you can, AmigaOS emulates the old Amigas, and can also take advantage of the updated functionality.
Audience question: as an old Amiga user, have they fixed the biggest problem, that the entire file system was corrupted when the machine crashed?
Yes, there are a few new file systems that aren't as sensitive.
Audience question: Have they removed the Guru meditation?
Yes, I'm sorry, they've replaced it with the Grim Reaper.
So the guru is gone, but problems persist.
I'm going to start by showing the parts in a typical Java installation, so we'll get a common ground to start from.
In essence, it's these four parts. And I'm going to go through them one by one.
We'll start with the JVM.
The java Virtual Machine is an executable file, usually java.exe.
It execute bytecode, and bytecode is the JVM's internal instructions, just like an x86 processor has x86 instructions, and PPC has PPC instructions.
The JVM translates from bytecode to processor instructions.
In the most simple case, it's relatively easy. One instructions have its obvious counterpart.
Sometimes one bytecode is several processor instructions, and so on.
It is however a rather slow process, if you take the easy way.
If you want more a advanced JVM, you have to do various smart things.
The JVM also handles memory and that stuff.
Going right we come to the class library.
And this is basically the Java SE standard.
The class library are the standard classes you use when youäre developiong Java programs.
And it's basically Oracle that decides how this should look.
And if you know your Java, you recognize all the standard classes, in the java packages.
This is stuff like handling lists, writing to the console, open files, and, handling XML and various things.
In order to for instance open a file, we need to somehow get access to the underlying operating system.
For this we have the native library.
And this is the way from the class library, which is the same for all JVM's,
but the native library is different, depending on the operating system.
When we're on Windows, the native library is a DLL, Unix/Linux uses shared objects, and on AmigaOS its library files.
And this is basically the parts we have in a JVM.
And now I'm going to show what alternatives we have for these parts.
The class library and the native library are closely tied together.
And there is in essence two choices: OpenJDK from Oracle, and GNU Classpath.
Open JDK supports the later Java versions 7, 8 and 9.
In the beginning OpenJDK wasn't "Open"
Somewhere between Java 6 and 7 that Sun decided to open up JDK and make it open source.
Before that, around 1998 the JDK was still closed source.
And then some people started GNU Classpath, which is an open source version of the Java standard.
They implemented everything in the Java standard from scratch.
And when OpenJDK became Open, people stopped developing for GNU Classpath.
A lot of people who started with GNU Classpath, are now developing for OpenJDK.
Some work at Oracle, and some develop in their spare time.
A few different JVM options
What you're probably using today is Oracle's hotspot,
which is, if I'm not mistaken, a combination of JRockit and HotSpot.
JRockit is actually a JVM developed by a Swedish company, later bought by Oracle.
Some of the JRockit developers are like working a t Oracle now.
Microsoft and MacOS had their own JVMs up until 2001.
Or rather, Windows had its to 2001, and Mac had its until OSX.
But then they skipped them, and let people decide themselver
Then we have onw called "Kaffe".
Its open source, and it support GNU Classpath
It also exists for Classic Amigas, i.e. the 68k processor.
The Jamiga project also has it s own virtual machine, which also can run on Classic Amigas.
Then there's a nother variant, GCJ, GNU Compiler for Java.
Which compiles either java code, or bytecode, to machine dependent code.
So the bytecode is translated to x86 or PPC code.
So you get a binary which needs to be compiled for each new architecture.
Then I can also mention Dalvik which is Android's VM.
And there's a small dispute, if Dalvik isn't in fact JamVM, where Google took the JamVM code and called it Dalvik.
But, lets focus on this VM JamVM.
It's developed since 2003, written in C, with some assembler.
It uses Posix threads, and it supports PowerPC.
So I thought this was good and interesting.
So instead of continuing JAmiga's VM, I began looking at using JamVM.
And that is what I've done.
In teh beginning it only supported GNU Classpath, but then when OpenJDK became open, it supports that aswell.
So when I'm developing, I'm porting JamVM.
A small summary. The JVM is JamVM
The class library is GNU Classpath, since that is what original JAmiga supported.
So I've continnued with that.
Native libraries are .library, and operating system AmigaOS 4.1.
I can talk a bit about the interface of GNU Classpath.
From the class library, via the native library down to the operating system.
And there's a number of different native libraries.
And these libraries corresponds to the Java packages.
Comparing this with OpenJDk, they have one big library for all classes
A small screen shot over GNU Classpath file structure.
On the right side we see the Java standard class "java.lang.System".
This has some connectiosn down to the operating system.
And those connectiosn can be found in the "java.lang.VMSystm" class.
And that is a pretty nice connection.
If we have a Java class, wee know which native class we should look in, to find connections to the OS.
In OpenJDK it isn't quite as nice, but I think they're trying to achieve that.
And now we're going to run some Amiga.
I'm going to show how it looks when you run a Java program, and what happens in the Java code.
So, now there's going to be some code.
Here we have a small Java program.
And here we have a main method that will print to the console "Hello Uppsala".
I.e. "Hello World" in Java.
And we're going to see what happens "under the hood".
Audience question: is your laptop an Amiga machine?
No.
No. Its an Ubuntu.
The amiga is at home, it's to big to take with me.
So this is just pictures.
We begin here in "Java.lang.System" "System" is a class in the java standard.
And then we have an object "out" here.
And if we go to the System class, we'll find that "out" is a PrintStream.
And if you know your Java, you know that PrintStream has a method "printline", which print a line to the stream.
Then we need to look at what "out" is initialised to.
And then we see this VMSystem class, which has a method "makeStadnardOutputStream".
So we move along to that class.
And now, this is VMSystem. I.e not a Java standard class, but a aprt of Gnu CLasspath..
And here we have a method "makeStandradOutputStream"
This returns a PrintStream, which wraps around a BufferedOutputStream that wraps around a FileOutputStream...
If you know your Java, you know about these streams... but we'll ignore that for now.
The main thing here is the "FileDescriptor.out".
This is just ordinary Java code.
But this "FileDescriptor.out" is a bit interesting.
So we move on that. We end up in a new class: "FileDescriptor"
And that has an object named "out" up there.
And.. that is a FileDescriptor object, which has an parameter FileChannelImpl.out, again.
So we move on to the class "FileChannelImpl".
And there we find the object "out", somewhere... There!
And if we look here; here we load our library "javanio".
So when this line is executed we're going to open "javanio.library". If this was Windows, we would've opened "javanio.dll".
We continue with "out".
Down here we see "out=ch". And "ch" we previously set to a FileChannelImpl.
Which is wrapped around a "VMFileChannelImpl.getStandardOut()".
So we move along to the "VMFileChannelImpl" class
And then we see the method "getStandardOut()"
And that methd is here "getStandardOut", which return a new VMFileChannel
And calls a method "stdout_fd", which is here, and it has no method body...
However, it has a intereseting word here: "native"
This means, that this call will be made to some sort of native library.
And now we will go from Java to C.
So this is C code.
And this is the function that is executed when we call this native method.
And, now,m if you know your Amiga, you might recognize this "IDOS->Output()".
This is a C function in Amigas SDk, which returns a pointer to the console.
So the pointer to the console is returned into the Java code, and going all the way back...
So, somewhere here in the System.out, there is a small pointer to our C function.
So this is some explanation to why Java is a bit slow to start up.
Aroudn 1995-1996 it took a long time to start a JVM, since all these classes had to be loaded on start-up
It is also a bit hard to find errors, when you don't know where you are.
This call.... er... eh
This call, from Java code to C code, looks a bit magic.
And it is a bit magic, but not much.
How does the JVM know which native method it should find?
From out antive libaray we can export different functions.
In the Java standard, it is defined that all native functions will have a standard name,
with a prefix, followed by the java package, method name and arguments, so the VM can find the method.
And with these small header definitions in the C code, the compile knows that these functions should be exported
But this is not how it works on the Amiga.
In the Amigas native libraries we only export on function "getLibraryContent"
And that returns a strcture where the JVM can do the lookup.
So that is one difference in Amiga.
Then ,some more code. A different example.
We're going to look at the class VMSecureRandom.java
The VM prefix tells us that there might be antive calls in here.
And this class generates a random seed, which is used by f.i. cryptography.
And one of my users that tested Jamiga, found a small crypto library
However, when executing it, the entire machine locked up.
And this is the VMSecureRandom class. The detalis aren't important.
But here we have the method "generateSeed", that generates our seed.
It does this by starting 8 threads that spins, and increments a counter,
and then randomly they will end, and then we'll end up with a random value.
And it was here that JVM started 8 threads, got into a (unsolved) race condition.
however, I managed to shorten this method to this.
Here we instead open a file from the Amiga device "Random:"
Which generate random numbers.
So, this method became much shorter, and a lot faster.
As an example we have here a variant from a Unix flavor, wirh a native call to his C code.
And this is C++, which with its object orientation maps a bit better to Java.
And just for the fun of it, we can look at the Win32 variant.
And this just throws an exception, that this method isn't supported on Win32.
Oh no! The Guru meditation!
Not at all planned. Oh no. How annoying.
Another problem i had, was how these threads are handled.
I experienced some problem when adding network support
I started a Java program which opens a socket
And this socket should talk to some other server, and send data to it.
And I thought it might be nice to put in its own thread, so the main thread can do other stuff.
We create a socket, and a new thread.
And then I try to read from the socket here.
But then I got this error: apparently, the socket, isn't a socket!
Much strange.
But if you read the Amiga docs...
You'll find that this socket only exists within this process.
There are ways to circumvent this, they are bit troublesome.
So instead I here created a new socket process.
So instead of sending the socket ID, I instead send a reference to the process.
We'll continue with these threads.
I mentioned that JamVM uses Posix-thread, where AmigaOS has processes.
Posix-threads are a bit more lightweight than AmigaOS' processes.
The AmigaOS processes has a few connections to DOS library and such.
Audience question: do they still have all that old DOS stuff, like BCPL and processes.
It's sort of all gone in Amiga OS 4.
Audience: they had these heavy processes, and then "threads".
Ah, yes, yes, that's still there.
An AmigaOS process is a "task", which is more lightweight. But the Amiga process has connections to DOS.
And the "tasks" can't be used for disk I/O, so if you need that, you need a "process".
Here we've started a simple Java class, "Start thread", that actually doesn't start a thread.
We're going to see how this looks when its running on the Amiga
Each new JVm instance, has beside the main process, also have three JamVM specific Amiga processes.
We have a Reference handler, Finalizer, and Signal handler.
Reference handler handles garbage collection, i.e. frees created objects.
The Finalizer runs the "finalize()" method on objects that's been garbage collected.
And the Signal handler handles signals sent to the program.
So it kind of looks like this.
And now I'm going to end this, so why not try and end this Java program by pressing Ctrl-C.
Ctrl-C is handled by the signal handler.
And when it gets the Ctrl-C it executes the Java method System.exit and VMRuntime.exit().
And then it also executes the native c-function exit().
The problem with running exit(), is that only the Signal handler process is ended.
Like i said, Amiga processes are a bit bigger than Posix-threads.
If this was Posix-threads, an exit() would've ended the main process, which would've ended the Posix-threads aswell.
But not in the Amiga case.
So instead, we run the Java methods in the Signal handler.
And then we send the Ctrl-C signal back to the main process.
Receiving that signal, the main process ends the three subprocesses, frees memory,closes libraries, and then exists.
And with that, I'm almost done.
Current status: Jamiga is at version 1.2, downloadable from http://www.os4depot.net.
There's also a few automatic updates available.
Somewhat completet support for Java 1.5, however no graphics or AWT.
I also have a small Twitter client, which uses Twitter4j.jar
Its very simple, this is a command line tool you can run,
which creates a small tweet.
Fantastic! The technology moves forward, even for the Amiga.
The plan ahead is to support OpenJDK
And this a small test i ran, which shows that I'm missing java.libraray, which I must implement.
JamVM supports OpenJDK, out of the box.
I'll also try to fix graphics stuff.
Just to mention a few ways to build OpenJDK.
You can either build it like Oracle wants you to.
One though I had was to build OpenJDK, grab the class files, and then just iteratively see what's missing.
Alternatively, you can build it using IcedTea, which is a way to build OpenJDK using free GNU tools.
When you're building using OpenJDK, I think there's still some thing that aren't completely open source.
If I'm not mistaken.
With IcedTea, you can also do cross compiles, so i can compile Jamiga-stuff on that.
Otherwise I have to compile everything on the Amiga, and it actually isn't that fast.
And that's where I am right now.
If you want more information, you can follow me on twitter or look at my blog. If you want info on Amiga, you can go to http://amigaos.se
That's it. Thank you! Questions?
Audience: what was the biggest challenge? Is it this with the threads?
Currently its cross-compiling OpenJDK, but previously it was...
... mostly time... to find the time to fix everything.
Much of the work isn't very advanced, but it's these sort of bugs that is the hardest part.
Audience: what is the process model on the new Amiga? Back in the days, all memory was shared, and you could peek wherever you wanted.
It's not possible to do that anymore, if you do that, the Grim Reaper will appear.
Audience: But wasn't that the case in Os 3.1. You could enable the MMU somehow.
Eh... er...
Yes, that's correct.
Audience: but the model was to send pointers.
Yes, er, that's still kind of like it is.
When you allocate memory, you can tell it to be"public" so other processes can reach it.
But you can also say that it's private, which is the preferred way.
But when two processes need to talk to each other, the memory needs to be "public".
Audience: and "public" is globally, shared?
Yes.
Audience: Have you found functions not available on Amiga? You mentioned the crypto-secure-random....
Audience: ...but have you found something where you had to port a third party library.
no.. no.. well.
The JVM and GNU Classpath has a few dependencies, but most them are available.
Or, well, the Posix-threads doesn't exist.
Or, there is a support for Posix-threads, but that implementation lacks a few things.
So I made my own Posix-thread implementation which is very Jamiga specific.
So you can't use anywhere you like, sadly, but it works for JAmiga.
Audience: You mentioned AWT, but why not SWT?
Er... SWT.... isn't that Swing in the background? Or is that AWT?
Audience: SWT has its own native libraray, and is nät oart of the java standard.
Audience: so SWT isn't standard, and that's why you don't mention it?
Audience: (some discussion on SWT, AWT, etc): SWT is horrible. Don't go there.
Sounds like I shouldn't bother with SWT... atleast not now.
Audeince: Do you have any more commiters in the project?
I had one who helpd with some MorphOS parts, but, no, now its just me.
And lately, it's not been much from me either.
Audeince: What about test code. Does Rocale have that?
Yes... Oracle has some test-sets, JTreg I think its called. I haven't looked at that much.
However, GNU Classpath has "Mauve", which is an entire test suite for all Java classes.
If you look at my blog, I've listed what is tested, and I think like 80 % is covered.
But, yes. Test suite exists.
Thank you!
A movie by Joel Edberg