μJ, A Java Virtual Machine For Microcontrollers

[Dimitri] sent in a project he’s been working on that implements a Java Virtual Machine purely in C, and is easily portable between microcontrollers such as the AVRs and PICs we normally see, ARM devices, and even the lowly 386.

Before going into the ‘how’, [Dimitri] first covers why he wanted to run Java bytecode on a microcontroller. Basically, he found existing solutions like the Arduino environment too complex for people just wanting to program a chip. Arduino and PICAXE require C-like syntax and pointers; not the easiest thing when everyone and their mother can program in Java.

As for how [Dimitri] managed to pack a JVM into a microcontroller, that’s another story entirely. Everything in the JVM, from double, long, and float data types to exceptions, neat thread-related functions such as ‘synchronize’ and even methods such as String.charAt() and String.length() are completely optional. If your microcontroller is too small, just disable the functions you don’t need.

As for how well – and how fast – μJ is able to run, [Dimitri] threw up a demo of an ATMega644 and PIC24 running his JVM and a small Java app. You can check those videos out after the break, or just download the source for μJ on [Dimitri]’s site.



78 thoughts on “μJ, A Java Virtual Machine For Microcontrollers

  1. Quite pointless actually. What is the purpose of a uC? To control other electronics, isn’t it? If the person using a uC has the knowledge to assemble a simple electronic circuit around the uC, then why wouldn’t that person be capable of writing a few lines in C or even in arduino language (C superset)?

    The PoC is neat but please just don’t tell me it is for yourmama to use.

      1. seriously? for your embedded system you’d rather program in straight assembly than compile from a high-level language? The Curiosity MSL is right now trundling around on Mars with software compiled from 2.5 million lines of C code.

      1. He didn’t say that. Did you stop reading when you hit arduino, or did you just choose to ignore the word “superset” ?

        (that said I think subset might have been a better word, but whatever. his intent should have been clear to you)

  2. Lots of kudos, especially for someone in his early 20s. Looking forward to trying this out on a few ARM boards – hopefully it’ll catch on. I’ll never use it on AVR, though.

  3. A vm is interesting when it can be used to execute code from an external source. Change the behavior of remote sensors by sending new java code to them for instance.

    Also running the java code direct from an sd card makes programs of virtually unlimited size possible.

  4. technically impressive, yet java on µc is absolutely disgusting. Why in hell would you put abstract code on a application specific electronic board?

    the worst part is we will surely get embeded javascript programming any time now…

  5. Not smoking anything – all university graduates here learn java whether they like it or not. Not all learn C, C++, or memory management. :)
    Plus, it was just a fun project. Additionally – unlimited code size is possible, since code is never loaded into RAM, and can easily not even be loaded to flash.

    Arduino environment is heavy, complex, and fragile. And it says a lot that I can interpret java and produce things that work FASTER than natively-compiled “arduino code”…

    Also….easy threading…very easy….

    1. If you know how to program, you can pick up the Arduino syntax in a very short amount of time.

      Implementing a VM for Java is, indeed, a neat thing, and it may get you enhancements like the ones you mention. However, I would stress those benefits over “Arduino is too complex for just wanting to program a chip.” People who know nothing about C, Java, or any other programming language can go from a blinking LED to more complex applications in a very short amount of time with an Arduino. (There are pluses and minuses to this, but they usually fall on the side of Arduino sacrificing things by making it *too* easy.)

      Again, stress the other technical aspects of your project. If you’re doing this so people who’ve studied Java can program uCs, you’re just enabling poor programmers. They should be able to learn a different syntax and program within the constraints of different setup.

      1. Couldn’t agree more about your point of enabling poor programmers. But given they are already enabled (see: ard….) i’d rather enable them in a way that they are less likely to shoot themselves in the foot with – no pointers, memory managed for you

    2. I like the concepts of VMs. If coded properly they work great. I also suppose more higher level code can be supported (Think serialization and sockets) so objects can be loaded and methods executed dynamically without having to power cycle.

    3. Dmitry u did succeed and even though it isnt preferred by many u showed it could be done and u gave good reason why this hack could be useful if not simply fun.

      haters need not be so critical and stop preaching and open your minds and see what benefits his approach offers.

      certainly there would be possible legalities if practiced on millions of devices but thats not the intent here nor would it be impossible to resolve.

      i do have a question though. do you believe it would require additional processing power overhead and thus greater battery usage as JVM powered?

      keep up the great hacks and dont let the haters get you down XD

      ps i hate coding am super slow and do i can see how java could be helpful here.

    1. Are you sure that C is a pre historic language?
      The Mars Curiosity rover is coded in C as someone pointed out.
      And most of your computer OS is probably written in C as well. As well as the OS on the mobile that you are using, be it Android or iOS or Symbian.

      1. C is 40 years old. That must be, what, half a million internet-years?

        Any language that in 2012 allows the programmer to write memory leaks, buffer overflows, etc, should avoided like the plague. Languages like Java eliminate entire classes of bugs and security issues. Sure, they’re not perfect, but they’re a major improvement over the glorified-asm that is C.

        So I will applaud any effort that makes it easier to move to a more modern language on any platform.

      2. “Any language that in 2012 allows the programmer to write memory leaks, buffer overflows, etc, should avoided like the plague.”

        Any “programmer” in 2012 who writes memory leaks, buffer overflows, etc should be avoided like the plague.

        It is not the language, it is a bad programmer that allows these things to occur.

        An experienced coder doesn’t need anything to manage memory, handle exceptions, prevent buffer overflows. Their good coding practices already cover those basics. The fact a good coder uses a language that promotes these kinds of things just means they’re a lazy programmer. Why reinvent the wheel when someone else did it for you?

        A bad coder needs someone else to manage memory leaks and buffer overflows because they don’t have good coding skills. They write utter crap, throw more crap at it when it doesn’t work as expected, then they search the internet for more samples of crap to cover up their own crap.

        Still can’t tell the difference? Bad programmers like magic_quotes.

      1. Dmitri, excellent work on your project, its outside the box thinking of new ways to do things that allows for the innovation of new ideas and inventions.

        FYI guys a very bad script-kiddie or good programmer can make anything crash. There are buffer overflow type problems that can be produced in Java(http://secunia.com/advisories/25295) as well as a multitude of issues the second you try to use Java ported into another program.

        Yes Java can be easy, No Java is not error proof. I agree with SavannahLion- Avoid the bad coder not the hard to use language. If a tool is too powerful for you to use properly use a safer one you know(like Java) til you know what the hell you’re doing.

  6. Dmitry, I congratulate you on the technical achievement. It is indeed pretty awesome. And if you did indeed get threading working correctly, I am doubly impressed.

    However, I must take exception to your reasoned replies. In order to meet the hackaday unofficial post guidelines, you need to make blanket statements, insult everything that isn’t in your own experience, provide no proof whatsoever, and you need to mention how long you have been programming 8-bit PICs for washing machines.

      1. @Dmitry Grinberg

        I don’t think it would take much for someone to find out.

        On a different topic..

        I’m thinking about implementing the “bios” for my m68k machine in Java now just for fun. Would you considering licensing uJ under one of the common opensource licenses?

      2. And good for you, but nobody is forcing you to use a JVM on your microcontroller. This is another new option for the people who choose to use it.

        Just cause it’s not right for you…

  7. I get the “ewww java” reply…I do, really. But, given that Java is th eonly thing that people coming out of college in USA can usually program, it seemed like a good choice. Arduino environment is limited (try to make a linked list in it, or, say, a hashtable). I wanted to give people who do not want to/cannot learn proper C some way to program these micros, and IMHO I succeeded.

      1. I also learned Haskel and Prolog beside compulsory Java (called object oriented language class actually).

        I also learned other fun things like Fujaba (google it).

        There was opportunity to learn C++ and other languages like Lisp too.

        But I think that it would be possible to graduate without touching anything behind Java.

  8. Amazing feat…even if the masses don’t like it…my hat is off to you, as I could definitely not do this. I went to your site and read into a bit. Looks like a lot of thought and work went into this…
    Don’t listen to the haters, they probably didn’t even go to your site.

  9. @ultrasounder

    that isn’t crippled in anyway, he ran a unmodified linux kernel, on that, the only problem is the speed, emulating a 32bit processor on a 8bit one, is really expensive, plus emulating a MMU. it just slow (too slow to be really useful)

    i’m your fan Dmitry, seriously.

  10. This project entirely captures the essence of a hack! right on :)

    admittedly i feel the same as most commentors here, though. Java is not an appropriate language for a uC, but the idea of being able to use threading and exceptions is fun because i’m lazy. And the aspect of volatile code that can be changed super easily is very exciting. That opens up a lot of cool possibilities!

  11. Without looking for the fishooks, and I’m sure there are some, the reason this interested me is that I have some seriously interesting code in Java that I wouldn’t mind porting to a micro project. I don’t want to rewrite it, then I’d have two versions to maintain. So anything that looks like helping port it is a heads-up for me.

  12. If you think Java is “easy”, you should look at Ruby, then get JRuby working with this so you can run some on a uC. That would rock.

    Also, if you’re weird, but not cool enough to like Ruby, there’s Jython. :p

    (Go ahead and flame me, Python junkies, but I still refuse to let the computer dictate how I format my source code! Also, I already know that people have run Python on uControllers before.)

  13. [Dmitry], this is quite impressive. I don’t know anything about Java, but I have certainly toyed with putting a high-level VM on a PIC.

    Occasionally I write functions in assembly instead of C, because I need absolute speed and can write much tighter code than the C compiler; but I wouldn’t dream of writing in assembly all the time. On the other hand, often I don’t even need C speed, and would prefer to write many functions in a higher-level language. VM bytecode is also more compact than compiled C, can be quickly uploaded to and run from RAM without flashing, or even run from external SPI memory. Having three languages at my disposal, all running seamlessly together, is my dream environment.

    I’ve written a partial, exploratory VM on the PIC. It was done strictly to get some idea of the projected difficulty, memory requirements, and performance of a full and useful VM. Given what I’ve learned from this exercise, and the memory/performance specs you’ve achieved, even knowing nothing about Java in particular I believe you’ve done an excellent job. I also like how you’ve allowed many features to be compiled out so the memory footprint can be adjusted.

    Have already downloaded uJ, and will give it a try soon.

    One other thought. I believe what you’ve done is also possible for Microsoft’s CIL, with similar difficulty, memory requirements, and performance; but could allow coding in many high-level languages, instead of just one. No one’s done that yet, at least within the realm of the MCUs you’re targeting. Existing projects like DotNetAnywhere include at least some JIT compilation in the VM, which makes it too big. Could be a very interesting area to explore.

    1. Well, in java (unlike CIL, if i remember correctly) most ops are typed, that is to say there is a separate op for addition of ints, different from one for longs, or floats) this makes it easier to remove features.

      I’ve considered CIL, but it did not catch my eyes as much as java did. As you had, i considered a custom VM, but writing a good compiler would make it a huge task – java already has a compiler, so all I had to do was write my own little post-compiler (classCvt) to clean up the remaining mess. In fact, classCvt can be used to do all kinds of other optimizations, which I might add later

      1. Didn’t know that about Java. You’re right, many of the CIL opcodes handle multiple types, with automatic conversion/promotion. My little prototype VM handled this, and I did allow for compiling out certain types (large ints, double and single floats); but it did take some extra work to allow this and still have reasonably efficient switch structures.

        And I agree writing a good compiler really sucks compared to writing a VM. To be avoided if at all possible!

    2. Microsoft already has something like this: the .NET Micro Framework. It was used in their SPOT devices, such as watches, etc. The source is even available under the Apache license!

      Speaking of existing implementations, Java Card is a tiny subset of Java designed to be run on smartcards. In fact, it’s so tiny that many of the usual Java features are missing, such as multi-dimensional arrays, garbage collection, etc. It shouldn’t be too hard to implement an interpreter for Java Card classes, though.

      Multi-application smartcards are a perfect example of why you’d want a VM on a microcontroller. The idea is that multiple vendors can load their applications on a single shared card with the VM enforcing separation between them. No application has to trust any other application.

      1. Not applicable. The .NET Micro Framework is *much* bigger. It most likely JIT compiles, rather than executing the CIL bytecode directly. The garbage collector is much more complex. And so on. I do believe it’s possible to fit a useful CIL VM into <64KB; but there's so many incompatible design decisions in the .NET MF implementation, that stripping it down to fit this target is probably harder than just writing a new VM from scratch.

  14. You know, I read the comments earlier today about how much shit people gave you for putting a java vm on micro, but hell, parallax runs basic, and so did the apple II. People still coded for it because basic was easy, and Java’s a pretty easy language, and its compiled.. This is a very cool project nice work!

  15. Dimitri,

    Don’t pay any attention to the scumbag assholes on HAD. They’re the side effect of a tech blog with mainstream appeal.

    That said, you’re far more likely to receive positive criticism on a site like news.ycombinator.com. Readers there are encouraged to know what the hell they’re talking about before hitting reply.

    Seriously, HAD, your readers do you no service by being a bunch of self-righteous armchair knowitalls.

    1. I remember that beasty. Wrote a weather monitoring and logging tool for it years ago.

      Ended up having to rebuild the OS with huge chunks re-written to free up some memory on it, but managed to get a really solid app which could log over a month’s data.

      I don’t see what the issue is with running a JVM on a µC. The demo shows it running nice and quick – not as quick as native (I add that to appease the C zealots), but in the real world, its results that matter.

      As for the memory management issue, handling pointers is tedious, and if you miss something that doesn’t crop up in testing then cripples your build when it’s running live, you’re stuck until you can re-write and re-flash.

      And yes, I do know that testing should be thorough, but people make mistakes and miss things – eliminate the need to manage your own memory, and eliminate that particular problem.

      Damn fine achievement!!

      Oh, and before the hailstorm of questioning, I program in Java, C, C++, C# and Objectove-C.
      I prefer Java to all of them.

    2. I remember that. Wrote a weather monitoring and logging tool for it a good few years ago.

      I ended up rebuilding the OS to remove a huge amount of unnecessary code to make enough space to store a decent number of logs.
      Ended up with a really stable system which could store 4 weeks worth of data.

      The C zealots will disagree and blame it on being a bad programmer, but managing you own memory is a tedious and problematic thing to do, and if you can avoid it, you can make the job so much faster.

      Java is a damn good language. Not a succinct as Scala, not as fast as C, but a brilliant all round language which is very scalable.

      I can get a project from concept to completion in Java faster than in C, C++, C# (although that’s damn close..), or Objective-C.
      Managing pointers yourself opens up any number of potential issues, and if you miss them in testing, you have a potentially dead build and a debugging nightmare on your hands.

      This is a damn fine achievement!

      I’m curious Dimitri – have you given your conversion tool a run through some Scala bytecode?

  16. C is thicker than pascal on these boards.ASM or BASIC all the way..and yeah U BET. your size limited in case you didnt know.when every bit and byte counts..you use what works best.He is using the Forth protocol.EVERYTHING is OPTIONAL. Try that in C sometime.PITA even with PASCAL, but IS possible.

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.