Improve error message for non-existent functions #337
No reviewers
Labels
No labels
bug
dependencies
documentation
duplicate
enhancement
github_actions
good first issue
help wanted
invalid
java
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
java-gi/java-gi!337
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "non-existent-functions"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Java-GI generates method handles for functions defined in GIR files. But those functions are not guaranteed to exist at runtime. This can happen for a variety of reasons:
We don't want to silently fail in this case; a runtime exception is the only responsible way to handle this.
In older versions of Java-GI, a non-existing function resulted in a
nullmethod handle, and callinginvokeExact()raised a NullPointerException.In later versions, I wanted to get rid of the null value, so I tried to return a "fallback" method handle to special method
Object functionNotFound(Object... args)that, because of its varargs argument, would always work, regardless of the type signature of the missing function. ThefunctionNotFound()method would throw a nice UnsupportedOperationException.However, in reality this didn't work, because
MethodHandle.invokeExact()is very picky about its parameter types, so now a very confusing exception was raised:java.lang.invoke.WrongMethodTypeException: handle's method type (Object[])Object but found [actual method type].To fix this, we could use
MethodHandle.invoke()instead ofinvokeExact(), but that can have a large performance impact. So I really want to keep usinginvokeExact().This PR introduces a new solution: When a function is not found and therefore the MethodHandle cannot be created, we use the new JEP 484 class-file API to generate a small class during runtime, with a single method with the exact type signature that was expected, that throws an UnsupportedOperationException. A MethodHandle to this on-the-fly-generated method is then installed so that when the user tries to execute it, the UnsupportedOperationException is raised. The exception even tells the user which function is missing.
Also added a test case.