Each platform has its strengths, and your choice depends on your requirements. What’s important is that together, Java ME Embedded and Java SE Embedded cover the embedded space from very small to very large, and give you a single development architecture to build embedded solutions easily and quickly.

Category Cloud

Meta

Blog Stats

9 comments

Thanks for the good abstract with strengths of each platform, even if I have problems to have a visionary understanding of the choice (below my better point of view for now).

I think personnally that it would be simpler if JavaME was a strict subset of JavaSE for determinist usecases but this would need realtime features (lacking currently in JavaME). I would understand a parallelism based on realtime-OSJavaME vs. general-purpose-OSJavaSE, but it seems currently false understanding and difficult given cohabitation of RTOS/GPOS don’t seem at maturity (realtime hypervisor).

Given time-constrained behaviour of sensors processing, it would be easier to understand restriction of GPIO, etc. to a sub-profile like JavaME and lack of UI in JavaME. Better understanding would also be allowed by co-running the two JVM, then by including JavaME as a part of JavaSE dedicated to realtime processing.

Is it possible to run the two in parallel on the same machine? I suppose yes but I have not tried JavaME on my Raspberry Pi (I want to test some software with JavaSE before doing electronics with GPIO). Is communication between the two VM simple and performant?

There are two separate issues here: 1) Alignment/compatibility between Java ME and Java SE and 2) real-time support.

Re. 1)
Oracle’s plan is to align ME and SE in terms of APIs and features in order to allow developers to move code and expertise easily between the two platforms. However, due to the significantly different use cases and limitations it is not desirable to make Java ME a strict subset of SE in all aspects.

Re. 2)
Real-time support is a complex topic. As you may know, real-time behavior has deep semantic implications across the system, from the application logic down to the transistor level. Note that the vast majority of embedded use cases DO NOT require hard real-time support. Real-time is a specialized use case that comes at a cost in terms of system performance, throughput, and complexity (see JSR 1 for real-time in Java SE). For Java ME Embedded we are looking at different options for lightweight real-time support … stay tuned.

As for “co-running” multiple Java runtimes on the same machine: You can certainly do that today (if your OS allows that) and you can have them communicate. But that won’t help in terms of real-time behavior. Not sure if that is the question you are asking.

The use-case in my head is mostly robotics with the following opinion on software architecture.

I see this problem as having real-time management of I/O but with a simple logic: this is something structured by time constraints (strong or weak constraints depending of the sensor / actuator type). Additionally, when some conditions are met, real-time processes send messages to the central manager (the complex logic). Simple logic must always process I/O at defined time.

In parallel of simple logic and using resources when available (near always because real-time requirements will be easily achievable only with simple logic letting room for others tasks), I would have a central manager taking a larger point of view of problem with complex logic (and not real-time).

This manager process extracted events by real-time simple logic, send others events to real-time logic and update this logic as needed. By example, for an horse:
– An update of logic is replacing feet control loop “gallop” by “trot” or inverse.
– An event send by manager process can be seen as an externally settable variable of simple logic, like, for the horse, the estimated slope (allowing small changes of muscular control in the feet control loop).
– An event received by manager process is a measurement, like shock when a foot hit ground.
– The complex logic of manager aggregate data, like those coming from eyes or shocks on ground to update estimated slope in feet control loop or in control of head position. Its good criteria is not real-time but some sort of efficiency (throughput, accuracy, soft real-time, etc.).

Given difficult compatibility between real-time and general-purpose, I would hope that system is mostly a very thin layer real-time running the real-time processes and giving all unused computing time to a general OS running complex logic.
– Low-level: real-time, few and small works, always working in time. A small system code like FreeRTOS or an hypervisor.
– High-level: complex control, works taking time to be finished and clearly unpredictable. A complex and elaborated system like Linux or any other general-purpose system.

Co-running the two Java on a Raspbian would be useful for testing communication between the simple logic and the complex logic even without real-time constraints realized on I/O side. My ideal architecture would be approximately: FreeRTOS with JavaME (probably using AOT) managing I/O with real-time processes and running, as a non-real-time process, a Linux with JavaSE (doing the complex information processing, compiling ahead-of-time the JavaME updates and installing them on real-time lower level).
This is similar to having a CPU with Linux-JavaSE for complex control and dedicated microcontrollers with JavaME for I/O management, but in only one silicon. By merging silicon, hardware architecture (CPU + microcontrollers) become simplified (CPU only) but software architecture take the old hardware architecture (general purpose OS as CPU + real-time processes as microcontrollers).

Generally, the partitioning between simple real-time logic and complex non-real-time logic you propose is the right approach. However, you still need to solve the implementation of real-time semantics on the ‘small’ (real-time) system. Further, once you have separate systems running real-time and non-real-time, you introduce the addition complexity of communicating results and events. If you want to have bounded communication time you need a special mechanism here, too.

To get back to the ‘small’ (real-time) system. Fundamentally, Java (like other higher-level runtime systems) tries to abstract system management away from the developer (for many good reasons). Primarily, automatic memory management is one of the key issues here. In most automated memory management systems there is some point where the garbage collector must stop all applications in order to guarantee the heap to be in a safe state to perform updates on. Garbage collection is very hard to make deterministic and it can hit at any time (whenever an object is allocated). These two issues together make real-time behavior in systems with automated memory management very hard. PS: AOT compilation does not help.

JSR 1 solves the problem by introducing separate real-time heaps and other special semantics and requires the developer to understand these and adapt his code accordingly, and it requires a specialized and complex Java runtime implementation.

For Java ME we are looking at a simpler approach, which introduces real-time behavior for the use cases we believe are relevant.

I am aware of problems with not deterministic GC and I was thinking to NIO direct buffers for sharing data.

I thought to AOT for solving a problem with real-time part: Java code is slow before sufficient use (JIT compiling will be called only after some use, so code is always slow at startup with JIT and this add a lack of determinism problematic for real-time). I have one other possible problem: smaller size of code window for compiler in JIT but I don’t want to have a too big window of code in compiler given real-time constraints.

Sorry for being irrelevant to JavaME. I think that I will look towards LLVM for real-time part of my problem, keeping only interest in JavaSE for general purpose part.

– AOT vs. JIT: Remember that real-time does NOT mean ‘fast’ execution. It means ‘deterministic’ execution. JIT compilation has no impact on real-time, it can happen in the background at low priority and can be interrupted at any time.
– NIO: Yes, NIO native buffers can speed up transfers, but they don’t guarantee deterministic behavior.
– Re. Java ME: Your input and real-time constraints are very relevant for Java ME. I’m just saying that these cannot be addressed with AOT, NIO, or execution on a separate CPU.

My problem with JIT for real-time is the source of the event triggering compilation of code. Then, I think my problem is probably mostly a semantic problem on AOT vs. JIT definition.
– For me, a JIT compiler is defining itself this event, typically by instrumenting code for finding hot parts of code. Then, in Hotspot, a method is always interpreted some time before being compiled by JIT and can be decompiled or recompiled or optimized after that.
– For me, in an AOT compiler, this compilation event is coming from user. By example, with my definition, I can call an AOT compiler during
program execution and then load the compiled result in the program (this is typical with any javax.script language at another level in Java: compiling script to bytecode and executing bytecode).

For my use-case, I will expect that compilation occurs always exactly when code is installed in real-time system before any execution of this code on real-time system.
Then I was calling this behaviour “AOT”, because I triggered compilation by asking to install code in real-time scope. But given it is only a part of the installation of code and is combined with transfer of compiled code to real-time scope and some others tasks, then user don’t call directly compiler, the name “JIT” is also perfectly good.

AOT and JIT are probably bad words for defining type or describing use-case of a Java virtual machine (e.g. Hotspot) or even only of a Java to native code compiler (e.g. Graal).