Running Java on RIOT-OS

Hi all,

I was wondering if the following would be *possible* to do (but not necessarily easy or the most elegant solution):

1. Fork the open source OpenJDK HotSpot Java Virtual Machine code (written in C). Refactor its code to automatically look at a particular memory address to load an executable JAR. 2. Compile that forked HotSpot VM code along with RIOT-OS and generate an executable for a given platform (say 32-bit ARM) 3. Flash the executable to the ARM chip 4. Flash a JAR to some ROM that is memory addressable from that chip 5. ... 6. Profit.

The intention here is that when the chip powers up, the RIOT-OS app (again a forked HotSpot JVM) loads an executable JAR from a specific place in memory. Boom: you're running Java on a RTOS.

I understand there are various projects out there attempting to run a JVM on an embedded tech (Java Card, etc.). But to my knowledge, none of these projects leverage the above proposed technique. And the reason for that is either:

1. I'm overlooking something obvious that makes this approach a non-starter; or 2. No one's ever tried this before

I'm willing to bet that its the former reason and not the latter. But in that case, I'd be interested in what the things are that I'm overlooking!

Thanks for any-and-all-help!

Hi Zac,

I think working actively on the now a bit dead GCJ project https://gcc.gnu.org/java/ would be more valuable than trying to pack a jvm + your application into an MCU, because I definitely think that the nature of the JVM platform doesn't make it runnable inside 512kb RAM.

Additionally I don't see why one would want Java and it's garbage collector thread in a RTOS, because you cannot do Real Time with Java, or really hardly otherwise the garbage collector thread will do it's work in the middle of your execution and you won't have a deterministic execution time.

You can naturally write the Java code in a really hard way: ensuring you preallocate all objects and never deallocating, that is never creating temporaries inside your main loop. Additionally JITting with a vm requires a cache where your store the compiled code.

The only way you would really get a good java support on an RTOS would be to change the runtime platform nature of java, that is :   - Compiling java as binaries, with an ABI similar to C++ one.   - Replacing the garbage collector concept with a reference counted automatic java reference management (std::shared_ptr like concept)

Then I think you could get it to work and find real use case with RTOS.

But you'll have some more issues, because Java object system uses function call dispatching mainly via a VTABLE as in C++ with the virtual keyword (i.e. Basically java has all functions being virtual, and by the way overridable), and this typically has a serious impact on performance, because the compiler doesn't know which code path will be taken before execution and cannot arrange the binary well for this scenario.

So I think java on the targets that riot is thought for might not be really interesting.

But you have C++ which is a really pretty language and offers all paradigms and expressiveness of Java and even more. If you know how to code in java, you can code as well so in C++, and by learning it you'll discover that you can employ other paradigms to improve readability and quality of your code (i.e. With tag & SFINAE dispatching, functional programming, compile time checking).

In case you still want to work on this, I would advice you to look at the LLVM platform, there exists already some projects capable of compiling java bytecode into LLVM bitcode, that you can in the end transform to a native executable well optimized. Actually the OpenJDK uses the LLVM platform to just-in-time compile java.

https://llvm.org/svn/llvm-project/java/trunk/docs/java-frontend.txt

Cheers,

Thanks Damien!

You mention several major problems with running Java + RIOT-OS (or really any RTOS) together, namely garbage collection and VTABLE-related performance issues. If I *did* go down the road of either GCJ or LLVM, would they somehow (magically) alleviate these problems that you mentioned?

Thanks again!

Thanks Damien!

You mention several major problems with running Java + RIOT-OS (or really any RTOS) together, namely garbage collection and VTABLE-related performance issues. If I *did* go down the road of either GCJ or LLVM, would they somehow (magically) alleviate these problems that you mentioned?

Thanks again!

No problem. :slight_smile:

I think the VTABLE issue is possibly the less important, so you might ignore it first.

But I imagine that implementing a kind of std::shared_ptr in place of the Java references might be the most complicated part, because I don't believe gcj nor llvm did something in this direction. But it has to be checked, googling a bit I found this paper : http://www.cs.cornell.edu/~rugina/papers/ismm06.pdf

Where the authors means they did it by detecting where the objects are unused.

But I think a first iteration would be to get it running with a garbage collector thread aside, and then if you want to do real-time applications you could replace the garbage collector with something like explained in the paper above or reference counting.

There also is something named escape analysis which may improve this :

After that I would personally still don't use java on an RTOS, due to the fact that java doesn't provide RAII, because sadly they had the idea of "finalizer()" functions, which in apparence looks like destructors but in fact don't get necessarily called, and therefore most of java code today is written in a way, where you have to think to close() native resources, and can't rely on automatic RAII resource management. But if this is a limitation that you can live with then I think this would all be great.

(I personally cannot bear it :p, I've got in a big product in java we shipped almost 80% of the bugs where missing calls to .close() leading to system lock because of resources not reopenable, or errors like too-much-files-open. We have been 1 year busy fixing such bugs, after 3 years of devs at a team of 6).

Cheers,

Hey,

You mention several major problems with running Java + RIOT-OS (or really any RTOS) together, namely garbage collection and VTABLE-related performance issues. If I *did* go down the road of either GCJ or LLVM, would they somehow (magically) alleviate these problems that you mentioned?

No, they're language intrinsic.

You should try to port one of the existing constrained MCU JVM implementations, like the one lejos [1] uses.

Kaspar

[1] http://www.lejos.org/