tweag/inline-java

Improve NoSuchMethod and NoSuchField error messages

Closed this issue · 1 comments

Looking up methods to invoke using the jvm or jni packages can produce errors like

Exception in thread "main" java.lang.NoSuchMethodError: fooMethod

if the types that the caller specifies on the Haskell side do not match the type signature of a method in a given Java class. Moreover, inline-java can produce these errors when handling references to instances of inner classes as discussed in #89.

The error would be much more helpful if it said something like

Exception in thread "main" java.lang.NoSuchMethodError: fooMethod  (Ljava.lang.Thread.State;)J
Possible type signatures for fooMethod in class :
(Ljava.lang.Thread$State;)J
...

The first line gives the JNI type signature that was used for the lookup. The following line gives the name of the class on which the lookup was made. And the following lines list the type signatures for all the available overloadings of fooMethod in the given class or any of its superclasses.

These errors are produced by getFieldID and getMethodID in the JNI package. A combination of isInstanceOf to identify the exception and then the reflection api of java to get the relevant method overloadings looks necessary.

Before:

Exception in thread "Thread-5" java.lang.NoSuchMethodError: replace

Now:

Couldn't find method
  java.lang.String replace()
in class java.lang.String.
The available method overloadings are:
  public java.lang.String java.lang.String.replace(char,char)
  public java.lang.String java.lang.String.replace(java.lang.CharSequence,java.lang.CharSequence)

🎉