Skip to content
This repository has been archived by the owner on Apr 29, 2024. It is now read-only.

Commit

Permalink
Some suggestions from PR Review 1
Browse files Browse the repository at this point in the history
    * Fix documentation punctuation.
    * Add HelperNotFoundException
    * Rename template files
  • Loading branch information
mahesh-hegde committed Jul 12, 2022
1 parent 9b85ac5 commit f820996
Show file tree
Hide file tree
Showing 10 changed files with 56 additions and 29 deletions.
2 changes: 1 addition & 1 deletion jni/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ This library contains:

This is intended for one-off / debugging uses of JNI, as well as providing a base library for code generated by jni_gen.

__If you're looking to interface a complete java library, look forward for `jni_gen`.__
__To interface a complete java library, look forward for `jni_gen`.__

## Platform support
The focus of this project is Android, since it already has a JVM and JNI allows interop with existing code and Platform APIs. Experimental desktop support exists for Linux using the JVM invocation API.
Expand Down
19 changes: 9 additions & 10 deletions jni/lib/jni.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@
/// the wrapper libraries with the executable. Thus it needs to be explicitly
/// placed in a accessible directory and provided as an argument to Jni.spawn.
///
/// This module depends on a shared library written in C, when using dart
/// standalone, it's your responsibility to:
/// This module depends on a shared library written in C. Therefore on dart
/// standalone:
///
/// * Build the library `libdartjni.so` in src/ directory of this plugin
/// * Bundle it appropriately with dart application
/// * Pass the path to library as a parameter to `Jni.spawn()`
/// * Build the library `libdartjni.so` in src/ directory of this plugin.
/// * Bundle it appropriately with dart application.
/// * Pass the path to library as a parameter to `Jni.spawn()`.
///
/// __JNIEnv:__
/// The types `JNIEnv` and `JavaVM` in JNI are available as `JniEnv` and
Expand All @@ -47,16 +47,15 @@
/// * On desktop platforms you can use JniEnv.ExceptionDescribe to print any
/// pending exception to stdout.
/// * On Android, things are slightly easier since CheckJNI is usually enabled
/// in debug builds.
/// * If you are not getting clear stack traces on JNI errors, check the
/// Android NDK page on how to enable CheckJNI using ADB.
/// in debug builds. If you are not getting clear stack traces on JNI errors,
/// check the Android NDK page on how to enable CheckJNI using ADB.
/// * As a rule of thumb, when there's a NoClassDefFound / NoMethodFound error,
/// first check your class and method signatures for typos.
///
/// This library exports the minimum foundations of JNI.
/// This file exports the minimum foundations of JNI.
///
/// For a higher level API, import jni_object.dart.
/// For a higher level API, import `'package:jni/jni_object.dart'`.
library jni;

export 'src/third_party/jni_bindings_generated.dart'; // currently export all
Expand Down
4 changes: 4 additions & 0 deletions jni/lib/src/jni.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:path/path.dart';
import 'third_party/jni_bindings_generated.dart';
import 'extensions.dart';
import 'jvalues.dart';
import 'jni_exceptions.dart';

import 'jni_object.dart';
import 'jni_class.dart';
Expand Down Expand Up @@ -34,6 +35,9 @@ DynamicLibrary _loadJniHelpersLibrary(
{String? dir, String baseName = "dartjni"}) {
final fileName = _getLibraryFileName(baseName);
final libPath = (dir != null) ? join(dir, fileName) : fileName;
if (!File(libPath).existsSync()) {
throw HelperNotFoundException(libPath);
}
final dylib = DynamicLibrary.open(libPath);
return dylib;
}
Expand Down
10 changes: 10 additions & 0 deletions jni/lib/src/jni_exceptions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,13 @@ class JniException implements Exception {

void deleteIn(Pointer<JniEnv> env) => env.DeleteLocalRef(err);
}

class HelperNotFoundException implements Exception {
HelperNotFoundException(this.path);
final String path;

@override
String toString() => "Lookup for helper library $path failed.\n"
"Please ensure that `dartjni` shared library is built.\n"
"If the library is already built, double check the path.";
}
16 changes: 15 additions & 1 deletion jni/test/exception_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,21 @@ import 'package:jni/jni_object.dart';

void main() {
if (!Platform.isAndroid) {
Jni.spawn(helperDir: "src/build");
bool caught = false;
try {
// If library does not exist, a helpful exception should be thrown.
// we can't test this directly because
// `test` schedules functions asynchronously
Jni.spawn(helperDir: "wrong_dir");
} on HelperNotFoundException catch (_) {
// stderr.write("\n$_\n");
Jni.spawn(helperDir: "src/build");
caught = true;
}
if (!caught) {
throw "Expected HelperNotFoundException\n"
"Read exception_test.dart for details.";
}
}
final jni = Jni.getInstance();

Expand Down
34 changes: 17 additions & 17 deletions jni/tool/gen_aux_methods.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import 'dart:io' as io;
import 'package:path/path.dart';

var targetTypes = {
final targetTypes = {
"String": "String",
"Object": "JniObject",
"Boolean": "bool",
Expand All @@ -17,7 +17,7 @@ var targetTypes = {
"Void": "void"
};

var resultConverters = {
final resultConverters = {
"String": (String resultVar) => "final str = _env.asDartString($resultVar);"
"_env.DeleteLocalRef($resultVar);"
"return str",
Expand All @@ -26,7 +26,7 @@ var resultConverters = {
"Boolean": (String resultVar) => "return $resultVar != 0",
};

var invokeResultConverters = {
final invokeResultConverters = {
"String": (String resultVar) => "final str = env.asDartString($resultVar);"
"env.DeleteLocalRef($resultVar);"
"env.DeleteLocalRef(cls);"
Expand All @@ -43,21 +43,21 @@ void main(List<String> args) {
return io.File(join(scriptDir, 'templates', name)).readAsStringSync();
}

final methodTemplates = getTemplate('JniObject_MethodCalls');
final fieldTemplates = getTemplate('JniObject_Fields');
final invokeTemplates = getTemplate('Invoke_Static_Methods');
final retrieveTemplates = getTemplate('Retrieve_Static_Fields');
final methodTemplates = getTemplate('jni_object_methods.dart.tmpl');
final fieldTemplates = getTemplate('jni_object_fields.dart.tmpl');
final invokeTemplates = getTemplate('invoke_static_methods.dart.tmpl');
final retrieveTemplates = getTemplate('retrieve_static_fields.dart.tmpl');

var outputDir = join("lib", "src");
var sInst = StringBuffer();
var sStatic = StringBuffer();
var sInvoke = StringBuffer();
var outPutPaths = {
final outputDir = join("lib", "src");
final sInst = StringBuffer();
final sStatic = StringBuffer();
final sInvoke = StringBuffer();
final outPutPaths = {
sInst: join(outputDir, "jni_object_methods_generated.dart"),
sStatic: join(outputDir, "jni_class_methods_generated.dart"),
sInvoke: join(outputDir, "direct_methods_generated.dart")
};
for (var s in [sInst, sStatic, sInvoke]) {
for (final s in [sInst, sStatic, sInvoke]) {
s.write("// Autogenerated; DO NOT EDIT\n"
"// Generated by running the script in tool/gen_aux_methods.dart\n");
}
Expand All @@ -70,7 +70,7 @@ void main(List<String> args) {
sStatic.write("extension JniClassCallMethods on JniClass {");
sInvoke.write("extension JniInvokeMethods on Jni {");

for (var t in targetTypes.keys) {
for (final t in targetTypes.keys) {
void write(String template) {
final resultConverter =
resultConverters[t] ?? (resultVar) => "return $resultVar";
Expand All @@ -91,7 +91,7 @@ void main(List<String> args) {
if (t != "Void") {
write(fieldTemplates);
}
var invokeResultConverter =
final invokeResultConverter =
(invokeResultConverters[t] ?? (String r) => "return $r");
void writeI(String template) {
final replaced = template
Expand All @@ -115,8 +115,8 @@ void main(List<String> args) {
sInst.write("}");
sStatic.write("}");
sInvoke.write("}");
for (var s in [sInst, sStatic, sInvoke]) {
var outputFile = io.File(outPutPaths[s]!);
for (final s in [sInst, sStatic, sInvoke]) {
final outputFile = io.File(outPutPaths[s]!);
outputFile.writeAsStringSync(s.toString(), flush: true);
}
io.stderr.write("Running dart format..\n");
Expand Down

0 comments on commit f820996

Please sign in to comment.