IOT_JVM linker-relocator
IOT_JVM will read the previously compiled object files and gather them in a bytecode executable by Duetware.
Running IOT_JVM
IOT_JVM is a command-line tool. However, it is automatically launched either from IoTize Studio or from Ride7:
-
In Iotize Studio, the launch is done from the main menu (Project | Run Java compiler), or by clicking on the 'gear' icon at the top left of the java code editing window.
-
In Ride-7, all you have to do is build the current project.
On the command line, the general syntax is:
IOT_JVM.exe [options list] filename.class
Unlike a 'C' linker, there is no need to specify all .class files. In the same way as when compiling, IOT_JVM will automatically search for the object files of the missing classes.
Options
The list of options is as follows:
| Option | Parameter | Description |
|---|---|---|
| -o | bcb filename | By default, the primary class name will be used and the destination directory will be that of the main object file suffixed by '.bcb'. |
| -l | map filename | By default, the primary class name will be used and the destination directory will be that of the main object file suffixed by '.map'. |
| -p | pathname | Path added for the search of imported packages |
| -v | none | Verbose output |
| -z | none | Compress output (-z, -z0, -z1 or -z2). See remark 2. |
| -m | size (kb) | Specify the amount (in kilobytes) of memory allocated for the heap |
| -c | size (kb) | Specify the amount (in kilobytes) of memory allocated for the code memory (bcb size) |
| -s | size (words) | Specify the number of word (32 bit words) allocated for the stack |
| -? | none | Print this message |
Remark
-
-c does not specifies the code size, but the minimum code size. Specifying more than the exact code size allows to execute the JAVA within a fixed buffer in RAM when debugging from RIDE7. A large buffer allows to overwrite the current bcb without replacing the buffer, even when the new code size is higher (but still lower than the specified minimum code size). When the new code is larger, it is mandatory to proceed to a complete reconfiguration.
-
Starting with version 2.57 (versioning for both for the firmware and for IOT_JVM.exe), the concept of compression levels was added:
-z0 is equivalent to 'no compression',
-z1 is equivalent to '-z' (typical gain of 50% over z0),
-z2 adds an additional compression level (typical gain of 12% over z1).
Operation
Reading object files (.class)
The main file is processed. When an external class is missing, the tool will scan the external directories to find that class. It will then process the found file and then continue until there are no more missing classes.
Linking to native classes/methods
IOT_JVM links the calls to the native functions. It means that it must know all the methods available in the JVM. Therefore, you must be sure that the versions of both IOT_JVM and Duetware are compatible.
Generating the BCB
The final file bcb is then built and optimized: the 'constant pools' are replaced by single tables that contain the list of methods, the list of classes, the list of fields, the list of constants,... All of these lists are optimized so that only the information necessary for execution is retained.
Compressor
Principles
A post-linker optimizer was introduced in 2023. The linker itself concatenates the list of (slightly optimized) .class files, but there are many redundancies between these files (typically the declaration of a method that belongs to another class is present twice: in the owning class and in the calling class). The compressor's job is mainly to factor out all the duplicate declarations and constants:

This compression tool usually shrinks the bcb file by a ratio of 2. Starting with version 2.57, the concept of compression levels was added. '-z2' provides an additional compression level (-z2) by recoding some assembly instructions. Because we are limited (for both the code and the data) to 16 bit addresses, the encoding of 32-bit instructions has been shrinked. Moreover, 16-bit references are also replaced by 8-bit references when possible. This is possible because the result of this link is fully static. In Iotize Studio, these 3 levels are indentified by Low (-z0), Standard (-z1) and High (-z2).
Why compress your code?
In its current version, the compression operates on an existing BCB file. This file therefore has an initial size of less than 64KB, and the process cannot reduce a file larger than 64KB to less than 64KB. It is therefore impossible to go from 100KB to 50KB, but it is easy to go from 50KB to 25KB.
However, reducing code size offers several advantages:
-
On small microcontrollers (for example, the STM32WL), the Java code size is limited to 16KB. Compression therefore allows us to start with a file size of around 32KB and end up within the 16KB limit.
-
In most implementations, Java byte code is executed from RAM where it is copied. Since RAM is a resource shared with resource-intensive functions (Wi-Fi, TLS, MQTT, etc.), it's always wise to minimize the space occupied by Java. However, this is minimal when a large amount of internal PSRAM is available.
Errors
Output by IOT_JVM
The most common error in IOT_JVM occurs when a standard method (or class) that is not supported by the JVM is used. There are many methods that have limited use in an embedded environment, and that should not be used (or reimplemented in Java).
Exception at Run-time(JVM)
See the 'Exception section'.
Exceptions that occur at runtime are reported with a code address and stack position. The code address is used to locate (in the list generated for IOT_JVM) the offending statement that threw the unprocessed exception. The cause of this error can then be understood by also using the error code issued.