IllegalArgumentException when calling a native function

Hello,

I just ran SDK getting started on both ESP32 Wrover Kit (Get Started - Create Apps and Build a VEE Port - MicroEJ Technology) and STM32F746 Discovery board (Get Started - Create Apps and Build a VEE Port - MicroEJ Technology).
Now I try to implement my own native function.

Here is the Java code:

public static void main(String[] args) {
		byte[] values = new byte[256];
		System.out.println("before native");
		fillValues(values);
		System.out.println("after native");
		int length = values.length;
		for (int i = 0; i < length; ++i) {
			System.out.println("Value[" + i + "]=" + values[i]);
	    	}
    }
private static native void fillValues(byte[] array);

It is running fine on ESP32 Kit but not on STM32F746. I got the following exception:

start
VM START
before native
Exception in thread “main” java.lang.IllegalArgumentException
at com.mycompany.Main.@M:0x800b854:0x800b880@
at java.lang.MainThread.@M:0x800d9e4:0x800d9fa@
at java.lang.Thread.@M:0x80103f4:0x8010400@
at java.lang.Thread.@M:0x80104e4:0x80104ef@
VM END (exit code = 0)

The exception seems to occur when I call the native function because I do not see the after native message.

Do you know what is going wrong ?

(I can attach the project with the C code but I did not find a way do do this)

Hi Hugo,

When building your application you can specify whether or not you allow to pass a non-immortal array to a native method. If it is not allowed, then an IllegalArgumentException is thrown at runtime when calling the native method.

If nothing is specified, by default, passing a non-immortal array to a native method is forbidden. You can configure this option by setting a property either when building the platform or when building the application.

In the platform configuration, to allow non-immortal array arguments for native methods, create a file mjvm/mjvm.properties next to your platform configuration file and add the line sni.nonimmortal.access=true. Then rebuild the platform.

You can override the property value when building the application. Define the property core.sni.nonimmortal.access in the JRE tab in VM arguments option. For example, to allow non-immortal array arguments for native methods, add the line: -Dcore.sni.nonimmortal.access=true.

In your use case, the ESP32 platform is configured so that it allows non-immortal arrays by default. In the STM32 platform nothing is specified so it is forbidden.

In the next MicroEJ Architecture release, an error message will be added to the IllegalArgumentException to help debugging this error.

Best regards,
Jerome

Hi Jerome,

Thanks for the tip. It works now.

BTW I searched in the Device Developer Guide ( https://developer.microej.com/packages/devdevguide-4.1-A/TLT-0784-MAN-DeviceDevGuide-1.1.0.pdf ) but nothing related to these options, is it normal ?

Also, it would be good to enable this option by default on all your default platforms.

Hi Hugo,

The Device Developer Guide has not been updated with this new option. We will add that.

The option was not set by default to prevent any compatibility issue with the platforms that have migrated to a new architecture. Some platforms may assume that an IllegalArgumentException is thrown at runtime.
I agree with you, it would be more convenient to enable this feature by default. We are considering modifying that.

Regards,
Jerome