Skip to content

pkgs/jni: Support Throwing Java Exceptions in Interface Impl. #1211

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 21 commits into from
Jun 25, 2024

Conversation

Anikate-De
Copy link
Contributor

@Anikate-De Anikate-De commented Jun 17, 2024

Items in this PR:


  • I’ve reviewed the contributor guide and applied the relevant portions to this PR.
Contribution guidelines:

Note that many Dart repos have a weekly cadence for reviewing PRs - please allow for some latency before initial review feedback.

@Anikate-De
Copy link
Contributor Author

To regenerate the bindings for jni, run the script in tool/generate_ffi_bindings.dart. And after changing the code generation in jnigen, you can generate all the bindings again using tool/regenerate_all_bindings.dart (in jnigen).

I haven't used the jnigen regeneration script yet as I was using a very particular use case of ok_http and manually regenerating the bindings when needed.

I will soon shift to a more general example of throwing exceptions in interface implementation to test this PR overall, and I will use tool/regenerate_all_bindings.dart then (thanks :))

@Anikate-De
Copy link
Contributor Author

Anikate-De commented Jun 17, 2024

Thanks for all the help! @HosseinYousefi

I temporarily edited the kotlin_plugin example within jnigen to demonstrate (and test) that this works. It has a very crude interface Divider. And a class DividerUser that catches any java.lang.ArithmeticExceptions thrown by the former.
We then deliberately throw the same, and expect a 0 as a result, since it will be caught in the Kotlin code.

No more java.lang.reflect.UndeclaredThrowableException!

If you feel the logical contents of this PR are satisfactory, then I can revert the last commit (Editing the jnigen example), and then get it ready for review.

@HosseinYousefi
Copy link
Member

Great job, @Anikate-De!

Yes, revert the temp commit and add the test to test/simple_package in jnigen. We currently cram all the usecases there. There are other tests for the interface implementation there as well.

@Anikate-De Anikate-De marked this pull request as ready for review June 19, 2024 06:30
Copy link

github-actions bot commented Jun 19, 2024

PR Health

Coverage ⚠️

Details
File Coverage
pkgs/jni/lib/src/jni.dart 💔 Not covered
pkgs/jni/lib/src/jprimitives.dart 💔 Not covered
pkgs/jni/lib/src/third_party/jni_bindings_generated.dart 💔 Not covered
pkgs/jnigen/lib/src/bindings/dart_generator.dart 💔 Not covered

This check for test coverage is informational (issues shown here will not fail the PR).

This check can be disabled by tagging the PR with skip-coverage-check.

License Headers ⚠️

Details
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
Files
pkgs/jni/lib/src/third_party/jni_bindings_generated.dart

All source files should start with a license header.

Unrelated files missing license headers
Files
pkgs/ffi/example/main.dart
pkgs/ffigen/example/libclang-example/generated_bindings.dart
pkgs/ffigen/example/shared_bindings/generate.dart
pkgs/ffigen/example/shared_bindings/lib/generated/a_gen.dart
pkgs/ffigen/example/shared_bindings/lib/generated/a_shared_b_gen.dart
pkgs/ffigen/example/shared_bindings/lib/generated/base_gen.dart
pkgs/ffigen/example/simple/generated_bindings.dart
pkgs/ffigen/lib/src/config_provider/config_spec.dart
pkgs/ffigen/lib/src/header_parser/clang_bindings/clang_bindings.dart
pkgs/ffigen/test/collision_tests/expected_bindings/_expected_decl_decl_collision_bindings.dart
pkgs/ffigen/test/collision_tests/expected_bindings/_expected_decl_symbol_address_collision_bindings.dart
pkgs/ffigen/test/collision_tests/expected_bindings/_expected_decl_type_name_collision_bindings.dart
pkgs/ffigen/test/collision_tests/expected_bindings/_expected_reserved_keyword_collision_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_comment_markup_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_dart_handle_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_enum_int_mimic_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_forward_decl_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_functions_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_imported_types_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_native_func_typedef_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_opaque_dependencies_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_packed_structs_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_regress_384_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_struct_fptr_fields_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_typedef_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_unions_bindings.dart
pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_varargs_bindings.dart
pkgs/ffigen/test/large_integration_tests/_expected_cjson_bindings.dart
pkgs/ffigen/test/large_integration_tests/_expected_libclang_bindings.dart
pkgs/ffigen/test/large_integration_tests/_expected_sqlite_bindings.dart
pkgs/ffigen/test/native_test/_expected_native_test_bindings.dart
pkgs/jni/lib/src/lang/jcharacter.dart
pkgs/jni/lib/src/third_party/generated_bindings.dart
pkgs/jni/lib/src/third_party/global_env_extensions.dart
pkgs/jnigen/android_test_runner/lib/main.dart
pkgs/jnigen/example/in_app_java/lib/android_utils.dart
pkgs/jnigen/example/kotlin_plugin/example/lib/main.dart
pkgs/jnigen/example/kotlin_plugin/lib/kotlin_bindings.dart
pkgs/jnigen/example/kotlin_plugin/lib/kotlin_plugin.dart
pkgs/jnigen/example/pdfbox_plugin/lib/pdfbox_plugin.dart
pkgs/jnigen/example/pdfbox_plugin/lib/src/third_party/org/apache/pdfbox/pdmodel/PDDocument.dart
pkgs/jnigen/example/pdfbox_plugin/lib/src/third_party/org/apache/pdfbox/pdmodel/PDDocumentInformation.dart
pkgs/jnigen/example/pdfbox_plugin/lib/src/third_party/org/apache/pdfbox/pdmodel/_package.dart
pkgs/jnigen/example/pdfbox_plugin/lib/src/third_party/org/apache/pdfbox/text/PDFTextStripper.dart
pkgs/jnigen/example/pdfbox_plugin/lib/src/third_party/org/apache/pdfbox/text/_package.dart
pkgs/jnigen/lib/src/bindings/descriptor.dart
pkgs/jnigen/lib/src/elements/elements.g.dart
pkgs/jnigen/test/jackson_core_test/third_party/bindings/com/fasterxml/jackson/core/_package.dart
pkgs/jnigen/tool/command_runner.dart
pkgs/native_assets_cli/lib/src/api/builder.dart
pkgs/native_assets_cli/lib/src/api/linker.dart
pkgs/native_assets_cli/test/model/checksum_test.dart
pkgs/swiftgen/swift2objc/lib/src/ast/ast.dart
pkgs/swiftgen/swift2objc/lib/src/ast/declarations/built_in/built_in_declaration.dart

This check can be disabled by tagging the PR with skip-license-check.

Package publish validation ✔️

Details
Package Version Status
package:ffi 2.1.2 already published at pub.dev
package:ffigen 13.0.0-wip WIP (no publish necessary)
package:jni 0.9.3-wip WIP (no publish necessary)
package:jnigen 0.9.3-wip WIP (no publish necessary)
package:native_assets_cli 0.6.1-wip WIP (no publish necessary)
package:objective_c 1.1.0-wip WIP (no publish necessary)
package:swiftgen 0.0.1-wip WIP (no publish necessary)

Documentation at https://github.com/dart-lang/ecosystem/wiki/Publishing-automation.

@HosseinYousefi
Copy link
Member

Also please add a changelog entry to jnigen about this.

@Anikate-De
Copy link
Contributor Author

Bumped up version to 0.9.3

@Anikate-De
Copy link
Contributor Author

There is a problem with throwing exceptions when the interface is consumed on a separate thread. (the reason why consumeOnAnotherThread is missing in the test case)

Quite like ok_http, if we throw the exception in that case, we run into a deadlock. For ok_http, it is default behaviour to terminate the connection with a java.net.SocketTimeoutException, but here, it pretty much leads to a forever wait cycle.

How could we solve this?

@HosseinYousefi
Copy link
Member

There is a problem with throwing exceptions when the interface is consumed on a separate thread. (the reason why consumeOnAnotherThread is missing in the test case)

Thanks for letting me know, this is very important! I'll checkout your branch and debug why this happens.

@coveralls
Copy link

Coverage Status

coverage: 92.069% (-0.05%) from 92.123%
when pulling d611416 on Anikate-De:support_java_excp
into a44ef95 on dart-lang:main.

@HosseinYousefi HosseinYousefi self-requested a review June 25, 2024 11:31
@HosseinYousefi
Copy link
Member

Added the test for the Future case.

Thanks @Anikate-De!

@HosseinYousefi HosseinYousefi linked an issue Jun 25, 2024 that may be closed by this pull request
@HosseinYousefi HosseinYousefi merged commit bd5b751 into dart-lang:main Jun 25, 2024
26 checks passed
@coveralls
Copy link

Coverage Status

coverage: 90.79% (-0.05%) from 90.841%
when pulling 3a7ff2a on Anikate-De:support_java_excp
into e5205d6 on dart-lang:main.

@coveralls
Copy link

Coverage Status

coverage: 90.79% (-0.05%) from 90.841%
when pulling 3a7ff2a on Anikate-De:support_java_excp
into e5205d6 on dart-lang:main.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support throwing Java exceptions in interface implementation
3 participants