-
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