[foreign] Improve error reporting when Java signature and native function layout don't match.

Jorn Vernee jbvernee at xs4all.nl
Tue Sep 25 13:27:41 UTC 2018


Hello,

Thanks for accepting my last contribution!

During testing I was running into an exception like this:

     Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 
Index 0 out of bounds for length 0
	at 
java.base/jdk.internal.foreign.NativeInvoker.invokeNormal(NativeInvoker.java:216)
	at 
java.base/jdk.internal.foreign.NativeInvoker.invoke(NativeInvoker.java:200)
	at com.github.jdnl.Main$MyLib$Impl/0x000000010009c440.exit(Unknown 
Source)
   	at com.github.jdnl.Main.main(Main.java:17)

The cause turned out to be a mismatch between the Java method signature 
and the native function layout:

     @NativeHeader(declarations =
         "exit=()v" // missing param
     )
     interface MyLib {
         void exit(int code);
     }

Since this exception is pretty cryptic, I'd like to contribute a patch 
that adds an explicit check for this to NativeInvoker, which does some 
basic verification that the two signatures match. With the patch I get 
this error instead (note the last 'Caused by'):

     Exception in thread "main" java.lang.RuntimeException: Failed to 
generate implementation for class interface com.github.jdnl.Main$MyLib
	at 
java.base/jdk.internal.foreign.LibrariesHelper.generateImpl(LibrariesHelper.java:65)
	at 
java.base/jdk.internal.foreign.LibrariesHelper$3.computeValue(LibrariesHelper.java:132)
	at 
java.base/jdk.internal.foreign.LibrariesHelper$3.computeValue(LibrariesHelper.java:124)
	at java.base/java.lang.ClassValue.getFromHashMap(ClassValue.java:226)
	at java.base/java.lang.ClassValue.getFromBackup(ClassValue.java:208)
	at java.base/java.lang.ClassValue.get(ClassValue.java:114)
	at 
java.base/jdk.internal.foreign.LibrariesHelper.getHeaderImplClass(LibrariesHelper.java:155)
	at 
java.base/jdk.internal.foreign.LibrariesHelper.bind(LibrariesHelper.java:241)
	at 
java.base/jdk.internal.foreign.LibrariesHelper.bind(LibrariesHelper.java:260)
	at java.base/java.foreign.Libraries.bind(Libraries.java:61)
	at com.github.jdnl.Main.main(Main.java:17)
     Caused by: java.lang.RuntimeException: Failed to generate method 
public abstract void com.github.jdnl.Main$MyLib.exit(int)
	at 
java.base/jdk.internal.foreign.BinderClassGenerator.generateMembers(BinderClassGenerator.java:153)
	at 
java.base/jdk.internal.foreign.HeaderImplGenerator.generateMembers(HeaderImplGenerator.java:103)
	at 
java.base/jdk.internal.foreign.BinderClassGenerator.generate(BinderClassGenerator.java:103)
	at 
java.base/jdk.internal.foreign.LibrariesHelper.lambda$generateImpl$0(LibrariesHelper.java:62)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at 
java.base/jdk.internal.foreign.LibrariesHelper.generateImpl(LibrariesHelper.java:61)
	... 10 more
     Caused by: java.lang.IllegalArgumentException: Java method signature 
and native layout not compatible: public abstract void 
com.github.jdnl.Main$MyLib.exit(int) : ()v
	at 
java.base/jdk.internal.foreign.NativeInvoker.of(NativeInvoker.java:127)
	at 
java.base/jdk.internal.foreign.HeaderImplGenerator.generateFunctionMethod(HeaderImplGenerator.java:130)
	at 
java.base/jdk.internal.foreign.HeaderImplGenerator.generateMethodImplementation(HeaderImplGenerator.java:121)
	at 
java.base/jdk.internal.foreign.BinderClassGenerator.generateMembers(BinderClassGenerator.java:150)
	... 15 more

And it is thrown when binding the interface, while the original 
exception was thrown when invoking the method.

I have kept the implementation fairly permissive, so things like binding 
`void m(Pointer<?> p)` to `(u64)v` (converting a pointer to an integer) 
should still be allowed, but maybe a stricter approach is preferable? I 
have added a test to verify that it catches some basic mistakes like 
missing parameters or return types.

Diff: 
https://gist.github.com/JornVernee/2fb68d70bad1aa807b50b77840117b27

I saw an RFR and JBS bug was made for my last contribution (thanks 
Sundar!), so I've not added 'RFR' to the subject line this time.

Regards,
Jorn


More information about the panama-dev mailing list