native
native copied to clipboard
☂️ Exceptions
What if someone wants to write some custom Java interface that is aware of the fact that it's going to be used in Dart. Maybe in this case the developer would want to catch Dart exceptions which we currently don't allow. I personally don't think this is of the highest priority. (Discussion https://github.com/dart-lang/jnigen/pull/376#issuecomment-1697132323)
~- [ ] Support handling DartExceptions in custom code~
Edit: We'll not support the above, it's encouraged to throw existing Java exceptions from Dart which is now supported.
Another thing that users might want to do is throw actual Java exceptions. This seems to be useful actually, and we could use the same Dart throw keyword to achieve this by checking if the exception thrown is of type JException.
- [x] #1209
However currently JException doesn't inherit JObject, we can change this by adding the Throwable and Exception types as core types to package:jni.
- [ ] dart-lang/native#567
Hi! This is in the context of the upcoming ok_http package using jnigen for the Kotlin package OkHttp. Specifically this PR
This is the problem we faced:
- To properly implement conformant redirection logic, we needed to use an interface
Interceptor, and further, needed to throw ajava.io.IOException, in theinterceptfunction of the implementation - We tried throwing this exception (after generating bindings of
IOException) using the Dartthrowkeyword, but that led to a crash with:java.lang.reflect.UndeclaredThrowableException - Neither did throwing a Dart exception work out for us. I'm unsure of how the JNI threading works, but it has always led to a deadlock in this case. And, while making requests, you would eventually face a
java.net.SocketTimeoutExceptionas it's OkHttp's predicted behaviour.
Workaround:
- We created a Kotlin function
addRedirectInterceptorthat implements the said logic. - Generated bindings for this function, and called it from the Dart end.
- Therefore, we basically, removed the JNI interop to throw
IOExceptionand decided to deal with it natively.
(Just in case someone faces the same problem and looks for how others dealt with it)
Would there have been a better way to resolve this? This comment is result of the PR review: Link
TL;DR - Faced problems with throwing exceptions within interface implementations using package:jni (both Dart & Java Exceptions) -> Lead to a Deadlock -> Decided to switch to native Kotlin code to deal with the exception-throwing logic -> Used the bindings of this custom class.
The problem is all thrown exceptions are currently wrapped in a DartException class, even Java exceptions.
You can fix this if you have time: https://github.com/dart-lang/native/issues/1209. I added some code pointers there.