[jnigen] Windows support (https://github.com/dart-lang/jnigen/issues/59)

diff --git a/.github/workflows/test-package.yml b/.github/workflows/test-package.yml
index dacfe94..d3d44e7 100644
--- a/.github/workflows/test-package.yml
+++ b/.github/workflows/test-package.yml
@@ -52,7 +52,7 @@
         if: always() && steps.install.outcome == 'success'
 
   test_jnigen:
-    needs: analyze_jnigen
+    needs: [analyze_jnigen]
     runs-on: ${{ matrix.os }}
     defaults:
       run:
@@ -60,7 +60,6 @@
     strategy:
       fail-fast: false
       matrix:
-        # Add macos-latest and/or windows-latest if relevant for this package.
         os: [ubuntu-latest]
         sdk: [stable, beta]
     steps:
@@ -90,9 +89,7 @@
           flag-name: jnigen_tests
           parallel: true
           path-to-lcov: ./pkgs/jnigen/coverage/lcov.info
-
-  ## TODO(#15): More minimal test on windows after fixing dev dependency.
-  ## i.e do not rerun analyze and format steps, and do not require flutter.
+        if: ${{ matrix.sdk == 'stable' }}
 
   test_summarizer:
     runs-on: ubuntu-latest
@@ -108,15 +105,36 @@
       - name: run tests using maven surefire
         run: mvn surefire:test
 
-  test_jni:
+  analyze_jni:
     runs-on: ubuntu-latest
     defaults:
       run:
         working-directory: ./pkgs/jni
     steps:
       - uses: actions/checkout@v3
-      ## Requires flutter to analyze example.
-      ## Using dart alone doesn't work.
+      - uses: subosito/flutter-action@v2
+        with:
+          channel: 'stable'
+          cache: true
+          cache-key: 'flutter-:os:-:channel:-:version:-:arch:-:hash:'
+      - uses: actions/setup-java@v2
+        with:
+          distribution: 'zulu'
+          java-version: '11'
+      - run: flutter pub get
+      - name: Check formatting
+        run: flutter format --output=none --set-exit-if-changed .
+      - name: Run lints
+        run: flutter analyze --fatal-infos
+
+  test_jni:
+    runs-on: ubuntu-latest
+    needs: [analyze_jni]
+    defaults:
+      run:
+        working-directory: ./pkgs/jni
+    steps:
+      - uses: actions/checkout@v3
       - uses: subosito/flutter-action@v2
         with:
           channel: 'stable'
@@ -130,12 +148,7 @@
           sudo apt-get update -y
           sudo apt-get install -y ninja-build libgtk-3-dev libclang-dev
       - run: dart pub get
-      - run: dart run bin/setup.dart
-      - run: flutter pub get
-      - name: Check formatting
-        run: flutter format --output=none --set-exit-if-changed .
-      - name: Run lints
-        run: flutter analyze --fatal-infos
+      - run: dart run jni:setup
       - name: Get dependencies
         run: dart pub get
       - name: Run tests
@@ -157,6 +170,53 @@
           dart run ffigen --config ffigen.yaml
           diff lib/src/third_party/jni_bindings_generated.dart __old_bindings
 
+  ## Run tests for package:jni on windows, just to confirm it works.
+  ## Do not, for example, collect coverage or check formatting.
+  test_jni_windows_minimal:
+    needs: [analyze_jni]
+    runs-on: windows-latest
+    defaults:
+      run:
+        working-directory: ./pkgs/jni
+    steps:
+      - uses: actions/checkout@v3
+      - uses: subosito/flutter-action@v2
+        with:
+          channel: 'stable'
+          cache: true
+          cache-key: 'flutter-:os:-:channel:-:version:-:arch:-:hash:'
+      - uses: actions/setup-java@v2
+        with:
+          distribution: 'zulu'
+          java-version: '11'
+      - run: Add-Content $env:GITHUB_PATH "$env:JAVA_HOME\bin\server"
+      - run: dart pub get
+      - run: dart run jni:setup
+      - run: dart test
+
+  test_jnigen_windows_minimal:
+    needs: [analyze_jnigen]
+    runs-on: windows-latest
+    defaults:
+      run:
+        working-directory: ./pkgs/jnigen
+    steps:
+      - uses: actions/checkout@v3
+      - uses: subosito/flutter-action@v2
+        with:
+          channel: 'stable'
+          cache: true
+          cache-key: 'flutter-:os:-:channel:-:version:-:arch:-:hash:'
+      - uses: actions/setup-java@v2
+        with:
+          distribution: 'zulu'
+          java-version: '11'
+      - run: git config --global core.autocrlf true
+      - run: Add-Content $env:GITHUB_PATH "$env:JAVA_HOME\bin\server"
+      - run: dart pub get
+      - run: dart run jnigen:setup
+      - run: dart test
+
   build_jni_example_linux:
     runs-on: ubuntu-latest
     defaults:
@@ -273,16 +333,6 @@
       - name: compare generated C bindings
         run: diff -qr src/android_utils _c
 
-  coveralls_finish:
-    needs: [test_jnigen, test_jni]
-    runs-on: ubuntu-latest
-    steps:
-      - name: Coveralls finished
-        uses: coverallsapp/github-action@master
-        with:
-          github-token: ${{ secrets.github_token }}
-          parallel-finished: true
-
   run_pdfbox_example_linux:
     runs-on: ubuntu-latest
     defaults:
@@ -330,3 +380,12 @@
           flutter build linux
         working-directory: ./pkgs/jnigen/example/pdfbox_plugin/example
 
+  coveralls_finish:
+    needs: [test_jnigen, test_jni]
+    runs-on: ubuntu-latest
+    steps:
+      - name: Coveralls finished
+        uses: coverallsapp/github-action@master
+        with:
+          github-token: ${{ secrets.github_token }}
+          parallel-finished: true
diff --git a/pkgs/jni/CHANGELOG.md b/pkgs/jni/CHANGELOG.md
index e61dbc4..cffdcf7 100644
--- a/pkgs/jni/CHANGELOG.md
+++ b/pkgs/jni/CHANGELOG.md
@@ -1,2 +1,5 @@
 ## 0.1.0
 * Initial version: Android and Linux support, JniObject API
+
+## 0.1.1
+* Windows support for running tests and examples on development machines.
diff --git a/pkgs/jni/README.md b/pkgs/jni/README.md
index 4cd7927..3f4ba5d 100644
--- a/pkgs/jni/README.md
+++ b/pkgs/jni/README.md
@@ -16,6 +16,9 @@
 
 __To generate type-safe bindings from Java libraries, use `jnigen`.__
 
+## SDK Note
+Dart standalone is supported, but due to some current limitations of the `pubspec` format, `dart` command must be from Flutter SDK and not dart SDK. See dart-lang/pub#3563.
+
 ## Version note
 This library is at an early stage of development and we do not provide backwards compatibility of the API at this point.
 
diff --git a/pkgs/jni/bin/setup.dart b/pkgs/jni/bin/setup.dart
index 38ed35c..ec62bb1 100644
--- a/pkgs/jni/bin/setup.dart
+++ b/pkgs/jni/bin/setup.dart
@@ -154,7 +154,23 @@
   } else {
     // pass srcDir absolute path because it will be passed to CMake as arg
     // which will be running in different directory
-    await build(options, srcDir.absolute.path, buildDir.path);
+    final jniDirUri = Uri.directory(".dart_tool").resolve("jni");
+    final jniDir = Directory.fromUri(jniDirUri);
+    await jniDir.create(recursive: true);
+    final tempDir = await jniDir.createTemp("jni_native_build_");
+    await build(options, srcDir.absolute.path, tempDir.path);
+    final dllDirUri =
+        Platform.isWindows ? tempDir.uri.resolve("Debug") : tempDir.uri;
+    final dllDir = Directory.fromUri(dllDirUri);
+    for (var entry in dllDir.listSync()) {
+      final dllSuffix = Platform.isWindows ? "dll" : "so";
+      if (entry.path.endsWith(dllSuffix)) {
+        final dllName = entry.uri.pathSegments.last;
+        final target = buildDir.uri.resolve(dllName);
+        entry.renameSync(target.toFilePath());
+      }
+    }
+    await tempDir.delete(recursive: true);
   }
 }
 
@@ -165,20 +181,6 @@
   cmakeArgs.add(srcPath);
   await runner.run("cmake", cmakeArgs, buildPath);
   await runner.run("cmake", ["--build", "."], buildPath);
-  final buildPathUri = Uri.directory(buildPath);
-  if (Platform.isWindows) {
-    final debugDir = buildPathUri.resolve('Debug');
-    for (var entry in Directory.fromUri(debugDir).listSync()) {
-      if (entry.path.endsWith('.dll')) {
-        final fileName = entry.uri.pathSegments.last;
-        final target = entry.parent.parent.uri.resolve(fileName);
-        log('rename ${entry.path} -> ${target.toFilePath()}');
-        entry.rename(target.toFilePath());
-      }
-    }
-  }
-  // delete cmakeTemporaryArtifacts
-  deleteCMakeTemps(Uri.directory(buildPath));
 }
 
 Future<void> cleanup(Options options, String srcPath, String buildPath) async {
diff --git a/pkgs/jni/example/pubspec.lock b/pkgs/jni/example/pubspec.lock
index 43745f0..cb53cc4 100644
--- a/pkgs/jni/example/pubspec.lock
+++ b/pkgs/jni/example/pubspec.lock
@@ -7,7 +7,7 @@
       name: archive
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "3.3.0"
+    version: "3.1.11"
   args:
     dependency: transitive
     description:
@@ -21,7 +21,7 @@
       name: async
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "2.9.0"
+    version: "2.8.2"
   boolean_selector:
     dependency: transitive
     description:
@@ -35,14 +35,21 @@
       name: characters
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.2.1"
+    version: "1.2.0"
+  charcode:
+    dependency: transitive
+    description:
+      name: charcode
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.3.1"
   clock:
     dependency: transitive
     description:
       name: clock
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.1.1"
+    version: "1.1.0"
   collection:
     dependency: transitive
     description:
@@ -56,7 +63,7 @@
       name: crypto
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "3.0.2"
+    version: "3.0.1"
   cupertino_icons:
     dependency: "direct main"
     description:
@@ -70,7 +77,7 @@
       name: fake_async
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.3.1"
+    version: "1.3.0"
   ffi:
     dependency: "direct main"
     description:
@@ -123,7 +130,7 @@
       path: ".."
       relative: true
     source: path
-    version: "0.0.1"
+    version: "0.1.0"
   lints:
     dependency: transitive
     description:
@@ -137,21 +144,21 @@
       name: matcher
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "0.12.12"
+    version: "0.12.11"
   material_color_utilities:
     dependency: transitive
     description:
       name: material_color_utilities
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "0.1.5"
+    version: "0.1.4"
   meta:
     dependency: transitive
     description:
       name: meta
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.8.0"
+    version: "1.7.0"
   package_config:
     dependency: transitive
     description:
@@ -165,7 +172,7 @@
       name: path
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.8.2"
+    version: "1.8.1"
   platform:
     dependency: transitive
     description:
@@ -198,7 +205,7 @@
       name: source_span
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.9.0"
+    version: "1.8.2"
   stack_trace:
     dependency: transitive
     description:
@@ -219,35 +226,35 @@
       name: string_scanner
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.1.1"
+    version: "1.1.0"
   sync_http:
     dependency: transitive
     description:
       name: sync_http
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "0.3.1"
+    version: "0.3.0"
   term_glyph:
     dependency: transitive
     description:
       name: term_glyph
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.2.1"
+    version: "1.2.0"
   test_api:
     dependency: transitive
     description:
       name: test_api
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "0.4.12"
+    version: "0.4.9"
   typed_data:
     dependency: transitive
     description:
       name: typed_data
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.3.1"
+    version: "1.3.0"
   vector_math:
     dependency: transitive
     description:
@@ -261,7 +268,7 @@
       name: vm_service
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "9.0.0"
+    version: "8.2.2"
   webdriver:
     dependency: transitive
     description:
@@ -271,3 +278,4 @@
     version: "3.0.0"
 sdks:
   dart: ">=2.17.5 <3.0.0"
+  flutter: ">=2.11.0"
diff --git a/pkgs/jni/pubspec.yaml b/pkgs/jni/pubspec.yaml
index 7940182..6ad55df 100644
--- a/pkgs/jni/pubspec.yaml
+++ b/pkgs/jni/pubspec.yaml
@@ -1,6 +1,6 @@
 name: jni
 description: Library to access JNI from dart and flutter
-version: 0.1.0
+version: 0.1.1
 repository: https://github.com/dart-lang/jnigen/tree/main/jni
 
 environment:
diff --git a/pkgs/jnigen/CHANGELOG.md b/pkgs/jnigen/CHANGELOG.md
index 22eaa56..f70e588 100644
--- a/pkgs/jnigen/CHANGELOG.md
+++ b/pkgs/jnigen/CHANGELOG.md
@@ -1,2 +1,6 @@
 ## 0.1.0
 * Initial version: Basic bindings generation, maven and android utilities
+
+## 0.1.1
+* Windows support for running tests and examples on development machines.
+
diff --git a/pkgs/jnigen/README.md b/pkgs/jnigen/README.md
index 7d282e3..642bcf1 100644
--- a/pkgs/jnigen/README.md
+++ b/pkgs/jnigen/README.md
@@ -11,3 +11,14 @@
 
 This is a work-in-progress project under Google Summer of Code 2022 program.
 
+## SDK Requirements
+Dart standalone target is supported, but due to some problems with pubspec, the `dart` command must be from Flutter SDK and not Dart SDK. See [dart-lang/pub#3563](https://github.com/dart-lang/pub/issues/3563).
+
+On windows, you need to append the path of `jvm.dll` in your JDK installation to PATH.
+
+For example, on Powershell:
+
+```
+$env:Path += ";${env:JAVA_HOME}\bin\server".
+```
+(If JAVA_HOME not set, find the `java.exe` executable and set the environment variable in Control Panel).
diff --git a/pkgs/jnigen/analysis_options.yaml b/pkgs/jnigen/analysis_options.yaml
index 543efa0..00d47a9 100644
--- a/pkgs/jnigen/analysis_options.yaml
+++ b/pkgs/jnigen/analysis_options.yaml
@@ -14,4 +14,5 @@
   rules:
     - prefer_final_locals
     - prefer_const_declarations
+    - unawaited_futures
 
diff --git a/pkgs/jnigen/bin/setup.dart b/pkgs/jnigen/bin/setup.dart
index fefbd67..c2937bf 100644
--- a/pkgs/jnigen/bin/setup.dart
+++ b/pkgs/jnigen/bin/setup.dart
@@ -17,5 +17,5 @@
       force = true;
     }
   }
-  buildSummarizerIfNotExists(force: force);
+  await buildSummarizerIfNotExists(force: force);
 }
diff --git a/pkgs/jnigen/example/pdfbox_plugin/src/third_party/pdfbox_plugin.c b/pkgs/jnigen/example/pdfbox_plugin/src/third_party/pdfbox_plugin.c
index 656a985..5128886 100644
--- a/pkgs/jnigen/example/pdfbox_plugin/src/third_party/pdfbox_plugin.c
+++ b/pkgs/jnigen/example/pdfbox_plugin/src/third_party/pdfbox_plugin.c
@@ -863,6 +863,7 @@
 }
 
 jfieldID _f_org_apache_pdfbox_pdmodel_PDDocument_RESERVE_BYTE_RANGE = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_pdmodel_PDDocument_RESERVE_BYTE_RANGE() {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_pdmodel_PDDocument, "org/apache/pdfbox/pdmodel/PDDocument");
@@ -873,6 +874,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_pdmodel_PDDocument_LOG = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_pdmodel_PDDocument_LOG() {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_pdmodel_PDDocument, "org/apache/pdfbox/pdmodel/PDDocument");
@@ -883,6 +885,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_pdmodel_PDDocument_document = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_pdmodel_PDDocument_document(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_pdmodel_PDDocument, "org/apache/pdfbox/pdmodel/PDDocument");
@@ -893,6 +896,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_pdmodel_PDDocument_documentInformation = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_pdmodel_PDDocument_documentInformation(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_pdmodel_PDDocument, "org/apache/pdfbox/pdmodel/PDDocument");
@@ -901,6 +905,7 @@
     return to_global_ref((*jniEnv)->GetObjectField(jniEnv, self_, _f_org_apache_pdfbox_pdmodel_PDDocument_documentInformation));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_pdmodel_PDDocument_documentInformation(jobject self_, jobject value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_pdmodel_PDDocument, "org/apache/pdfbox/pdmodel/PDDocument");
@@ -911,6 +916,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_pdmodel_PDDocument_documentCatalog = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_pdmodel_PDDocument_documentCatalog(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_pdmodel_PDDocument, "org/apache/pdfbox/pdmodel/PDDocument");
@@ -919,6 +925,7 @@
     return to_global_ref((*jniEnv)->GetObjectField(jniEnv, self_, _f_org_apache_pdfbox_pdmodel_PDDocument_documentCatalog));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_pdmodel_PDDocument_documentCatalog(jobject self_, jobject value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_pdmodel_PDDocument, "org/apache/pdfbox/pdmodel/PDDocument");
@@ -929,6 +936,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_pdmodel_PDDocument_encryption = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_pdmodel_PDDocument_encryption(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_pdmodel_PDDocument, "org/apache/pdfbox/pdmodel/PDDocument");
@@ -937,6 +945,7 @@
     return to_global_ref((*jniEnv)->GetObjectField(jniEnv, self_, _f_org_apache_pdfbox_pdmodel_PDDocument_encryption));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_pdmodel_PDDocument_encryption(jobject self_, jobject value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_pdmodel_PDDocument, "org/apache/pdfbox/pdmodel/PDDocument");
@@ -947,6 +956,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_pdmodel_PDDocument_allSecurityToBeRemoved = NULL;
+FFI_PLUGIN_EXPORT
 uint8_t get_org_apache_pdfbox_pdmodel_PDDocument_allSecurityToBeRemoved(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_pdmodel_PDDocument, "org/apache/pdfbox/pdmodel/PDDocument");
@@ -955,6 +965,7 @@
     return ((*jniEnv)->GetBooleanField(jniEnv, self_, _f_org_apache_pdfbox_pdmodel_PDDocument_allSecurityToBeRemoved));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_pdmodel_PDDocument_allSecurityToBeRemoved(jobject self_, uint8_t value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_pdmodel_PDDocument, "org/apache/pdfbox/pdmodel/PDDocument");
@@ -965,6 +976,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_pdmodel_PDDocument_documentId = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_pdmodel_PDDocument_documentId(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_pdmodel_PDDocument, "org/apache/pdfbox/pdmodel/PDDocument");
@@ -973,6 +985,7 @@
     return to_global_ref((*jniEnv)->GetObjectField(jniEnv, self_, _f_org_apache_pdfbox_pdmodel_PDDocument_documentId));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_pdmodel_PDDocument_documentId(jobject self_, jobject value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_pdmodel_PDDocument, "org/apache/pdfbox/pdmodel/PDDocument");
@@ -983,6 +996,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_pdmodel_PDDocument_pdfSource = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_pdmodel_PDDocument_pdfSource(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_pdmodel_PDDocument, "org/apache/pdfbox/pdmodel/PDDocument");
@@ -993,6 +1007,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_pdmodel_PDDocument_accessPermission = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_pdmodel_PDDocument_accessPermission(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_pdmodel_PDDocument, "org/apache/pdfbox/pdmodel/PDDocument");
@@ -1001,6 +1016,7 @@
     return to_global_ref((*jniEnv)->GetObjectField(jniEnv, self_, _f_org_apache_pdfbox_pdmodel_PDDocument_accessPermission));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_pdmodel_PDDocument_accessPermission(jobject self_, jobject value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_pdmodel_PDDocument, "org/apache/pdfbox/pdmodel/PDDocument");
@@ -1011,6 +1027,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_pdmodel_PDDocument_fontsToSubset = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_pdmodel_PDDocument_fontsToSubset(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_pdmodel_PDDocument, "org/apache/pdfbox/pdmodel/PDDocument");
@@ -1021,6 +1038,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_pdmodel_PDDocument_fontsToClose = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_pdmodel_PDDocument_fontsToClose(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_pdmodel_PDDocument, "org/apache/pdfbox/pdmodel/PDDocument");
@@ -1031,6 +1049,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_pdmodel_PDDocument_signInterface = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_pdmodel_PDDocument_signInterface(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_pdmodel_PDDocument, "org/apache/pdfbox/pdmodel/PDDocument");
@@ -1039,6 +1058,7 @@
     return to_global_ref((*jniEnv)->GetObjectField(jniEnv, self_, _f_org_apache_pdfbox_pdmodel_PDDocument_signInterface));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_pdmodel_PDDocument_signInterface(jobject self_, jobject value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_pdmodel_PDDocument, "org/apache/pdfbox/pdmodel/PDDocument");
@@ -1049,6 +1069,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_pdmodel_PDDocument_signingSupport = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_pdmodel_PDDocument_signingSupport(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_pdmodel_PDDocument, "org/apache/pdfbox/pdmodel/PDDocument");
@@ -1057,6 +1078,7 @@
     return to_global_ref((*jniEnv)->GetObjectField(jniEnv, self_, _f_org_apache_pdfbox_pdmodel_PDDocument_signingSupport));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_pdmodel_PDDocument_signingSupport(jobject self_, jobject value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_pdmodel_PDDocument, "org/apache/pdfbox/pdmodel/PDDocument");
@@ -1067,6 +1089,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_pdmodel_PDDocument_resourceCache = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_pdmodel_PDDocument_resourceCache(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_pdmodel_PDDocument, "org/apache/pdfbox/pdmodel/PDDocument");
@@ -1075,6 +1098,7 @@
     return to_global_ref((*jniEnv)->GetObjectField(jniEnv, self_, _f_org_apache_pdfbox_pdmodel_PDDocument_resourceCache));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_pdmodel_PDDocument_resourceCache(jobject self_, jobject value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_pdmodel_PDDocument, "org/apache/pdfbox/pdmodel/PDDocument");
@@ -1085,6 +1109,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_pdmodel_PDDocument_signatureAdded = NULL;
+FFI_PLUGIN_EXPORT
 uint8_t get_org_apache_pdfbox_pdmodel_PDDocument_signatureAdded(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_pdmodel_PDDocument, "org/apache/pdfbox/pdmodel/PDDocument");
@@ -1093,6 +1118,7 @@
     return ((*jniEnv)->GetBooleanField(jniEnv, self_, _f_org_apache_pdfbox_pdmodel_PDDocument_signatureAdded));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_pdmodel_PDDocument_signatureAdded(jobject self_, uint8_t value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_pdmodel_PDDocument, "org/apache/pdfbox/pdmodel/PDDocument");
@@ -1396,6 +1422,7 @@
 }
 
 jfieldID _f_org_apache_pdfbox_pdmodel_PDDocumentInformation_info = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_pdmodel_PDDocumentInformation_info(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_pdmodel_PDDocumentInformation, "org/apache/pdfbox/pdmodel/PDDocumentInformation");
@@ -2381,6 +2408,7 @@
 }
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_defaultIndentThreshold = NULL;
+FFI_PLUGIN_EXPORT
 float get_org_apache_pdfbox_text_PDFTextStripper_defaultIndentThreshold() {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2389,6 +2417,7 @@
     return ((*jniEnv)->GetStaticFloatField(jniEnv, _c_org_apache_pdfbox_text_PDFTextStripper, _f_org_apache_pdfbox_text_PDFTextStripper_defaultIndentThreshold));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_text_PDFTextStripper_defaultIndentThreshold(float value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2399,6 +2428,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_defaultDropThreshold = NULL;
+FFI_PLUGIN_EXPORT
 float get_org_apache_pdfbox_text_PDFTextStripper_defaultDropThreshold() {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2407,6 +2437,7 @@
     return ((*jniEnv)->GetStaticFloatField(jniEnv, _c_org_apache_pdfbox_text_PDFTextStripper, _f_org_apache_pdfbox_text_PDFTextStripper_defaultDropThreshold));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_text_PDFTextStripper_defaultDropThreshold(float value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2417,6 +2448,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_LOG = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_text_PDFTextStripper_LOG() {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2427,6 +2459,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_LINE_SEPARATOR = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_text_PDFTextStripper_LINE_SEPARATOR(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2437,6 +2470,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_lineSeparator = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_text_PDFTextStripper_lineSeparator(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2445,6 +2479,7 @@
     return to_global_ref((*jniEnv)->GetObjectField(jniEnv, self_, _f_org_apache_pdfbox_text_PDFTextStripper_lineSeparator));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_text_PDFTextStripper_lineSeparator(jobject self_, jobject value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2455,6 +2490,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_wordSeparator = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_text_PDFTextStripper_wordSeparator(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2463,6 +2499,7 @@
     return to_global_ref((*jniEnv)->GetObjectField(jniEnv, self_, _f_org_apache_pdfbox_text_PDFTextStripper_wordSeparator));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_text_PDFTextStripper_wordSeparator(jobject self_, jobject value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2473,6 +2510,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_paragraphStart = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_text_PDFTextStripper_paragraphStart(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2481,6 +2519,7 @@
     return to_global_ref((*jniEnv)->GetObjectField(jniEnv, self_, _f_org_apache_pdfbox_text_PDFTextStripper_paragraphStart));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_text_PDFTextStripper_paragraphStart(jobject self_, jobject value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2491,6 +2530,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_paragraphEnd = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_text_PDFTextStripper_paragraphEnd(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2499,6 +2539,7 @@
     return to_global_ref((*jniEnv)->GetObjectField(jniEnv, self_, _f_org_apache_pdfbox_text_PDFTextStripper_paragraphEnd));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_text_PDFTextStripper_paragraphEnd(jobject self_, jobject value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2509,6 +2550,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_pageStart = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_text_PDFTextStripper_pageStart(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2517,6 +2559,7 @@
     return to_global_ref((*jniEnv)->GetObjectField(jniEnv, self_, _f_org_apache_pdfbox_text_PDFTextStripper_pageStart));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_text_PDFTextStripper_pageStart(jobject self_, jobject value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2527,6 +2570,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_pageEnd = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_text_PDFTextStripper_pageEnd(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2535,6 +2579,7 @@
     return to_global_ref((*jniEnv)->GetObjectField(jniEnv, self_, _f_org_apache_pdfbox_text_PDFTextStripper_pageEnd));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_text_PDFTextStripper_pageEnd(jobject self_, jobject value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2545,6 +2590,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_articleStart = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_text_PDFTextStripper_articleStart(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2553,6 +2599,7 @@
     return to_global_ref((*jniEnv)->GetObjectField(jniEnv, self_, _f_org_apache_pdfbox_text_PDFTextStripper_articleStart));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_text_PDFTextStripper_articleStart(jobject self_, jobject value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2563,6 +2610,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_articleEnd = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_text_PDFTextStripper_articleEnd(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2571,6 +2619,7 @@
     return to_global_ref((*jniEnv)->GetObjectField(jniEnv, self_, _f_org_apache_pdfbox_text_PDFTextStripper_articleEnd));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_text_PDFTextStripper_articleEnd(jobject self_, jobject value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2581,6 +2630,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_currentPageNo = NULL;
+FFI_PLUGIN_EXPORT
 int32_t get_org_apache_pdfbox_text_PDFTextStripper_currentPageNo(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2589,6 +2639,7 @@
     return ((*jniEnv)->GetIntField(jniEnv, self_, _f_org_apache_pdfbox_text_PDFTextStripper_currentPageNo));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_text_PDFTextStripper_currentPageNo(jobject self_, int32_t value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2599,6 +2650,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_startPage = NULL;
+FFI_PLUGIN_EXPORT
 int32_t get_org_apache_pdfbox_text_PDFTextStripper_startPage(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2607,6 +2659,7 @@
     return ((*jniEnv)->GetIntField(jniEnv, self_, _f_org_apache_pdfbox_text_PDFTextStripper_startPage));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_text_PDFTextStripper_startPage(jobject self_, int32_t value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2617,6 +2670,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_endPage = NULL;
+FFI_PLUGIN_EXPORT
 int32_t get_org_apache_pdfbox_text_PDFTextStripper_endPage(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2625,6 +2679,7 @@
     return ((*jniEnv)->GetIntField(jniEnv, self_, _f_org_apache_pdfbox_text_PDFTextStripper_endPage));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_text_PDFTextStripper_endPage(jobject self_, int32_t value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2635,6 +2690,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_startBookmark = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_text_PDFTextStripper_startBookmark(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2643,6 +2699,7 @@
     return to_global_ref((*jniEnv)->GetObjectField(jniEnv, self_, _f_org_apache_pdfbox_text_PDFTextStripper_startBookmark));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_text_PDFTextStripper_startBookmark(jobject self_, jobject value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2653,6 +2710,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_startBookmarkPageNumber = NULL;
+FFI_PLUGIN_EXPORT
 int32_t get_org_apache_pdfbox_text_PDFTextStripper_startBookmarkPageNumber(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2661,6 +2719,7 @@
     return ((*jniEnv)->GetIntField(jniEnv, self_, _f_org_apache_pdfbox_text_PDFTextStripper_startBookmarkPageNumber));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_text_PDFTextStripper_startBookmarkPageNumber(jobject self_, int32_t value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2671,6 +2730,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_endBookmarkPageNumber = NULL;
+FFI_PLUGIN_EXPORT
 int32_t get_org_apache_pdfbox_text_PDFTextStripper_endBookmarkPageNumber(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2679,6 +2739,7 @@
     return ((*jniEnv)->GetIntField(jniEnv, self_, _f_org_apache_pdfbox_text_PDFTextStripper_endBookmarkPageNumber));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_text_PDFTextStripper_endBookmarkPageNumber(jobject self_, int32_t value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2689,6 +2750,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_endBookmark = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_text_PDFTextStripper_endBookmark(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2697,6 +2759,7 @@
     return to_global_ref((*jniEnv)->GetObjectField(jniEnv, self_, _f_org_apache_pdfbox_text_PDFTextStripper_endBookmark));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_text_PDFTextStripper_endBookmark(jobject self_, jobject value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2707,6 +2770,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_suppressDuplicateOverlappingText = NULL;
+FFI_PLUGIN_EXPORT
 uint8_t get_org_apache_pdfbox_text_PDFTextStripper_suppressDuplicateOverlappingText(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2715,6 +2779,7 @@
     return ((*jniEnv)->GetBooleanField(jniEnv, self_, _f_org_apache_pdfbox_text_PDFTextStripper_suppressDuplicateOverlappingText));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_text_PDFTextStripper_suppressDuplicateOverlappingText(jobject self_, uint8_t value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2725,6 +2790,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_shouldSeparateByBeads = NULL;
+FFI_PLUGIN_EXPORT
 uint8_t get_org_apache_pdfbox_text_PDFTextStripper_shouldSeparateByBeads(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2733,6 +2799,7 @@
     return ((*jniEnv)->GetBooleanField(jniEnv, self_, _f_org_apache_pdfbox_text_PDFTextStripper_shouldSeparateByBeads));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_text_PDFTextStripper_shouldSeparateByBeads(jobject self_, uint8_t value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2743,6 +2810,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_sortByPosition = NULL;
+FFI_PLUGIN_EXPORT
 uint8_t get_org_apache_pdfbox_text_PDFTextStripper_sortByPosition(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2751,6 +2819,7 @@
     return ((*jniEnv)->GetBooleanField(jniEnv, self_, _f_org_apache_pdfbox_text_PDFTextStripper_sortByPosition));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_text_PDFTextStripper_sortByPosition(jobject self_, uint8_t value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2761,6 +2830,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_addMoreFormatting = NULL;
+FFI_PLUGIN_EXPORT
 uint8_t get_org_apache_pdfbox_text_PDFTextStripper_addMoreFormatting(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2769,6 +2839,7 @@
     return ((*jniEnv)->GetBooleanField(jniEnv, self_, _f_org_apache_pdfbox_text_PDFTextStripper_addMoreFormatting));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_text_PDFTextStripper_addMoreFormatting(jobject self_, uint8_t value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2779,6 +2850,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_indentThreshold = NULL;
+FFI_PLUGIN_EXPORT
 float get_org_apache_pdfbox_text_PDFTextStripper_indentThreshold(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2787,6 +2859,7 @@
     return ((*jniEnv)->GetFloatField(jniEnv, self_, _f_org_apache_pdfbox_text_PDFTextStripper_indentThreshold));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_text_PDFTextStripper_indentThreshold(jobject self_, float value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2797,6 +2870,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_dropThreshold = NULL;
+FFI_PLUGIN_EXPORT
 float get_org_apache_pdfbox_text_PDFTextStripper_dropThreshold(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2805,6 +2879,7 @@
     return ((*jniEnv)->GetFloatField(jniEnv, self_, _f_org_apache_pdfbox_text_PDFTextStripper_dropThreshold));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_text_PDFTextStripper_dropThreshold(jobject self_, float value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2815,6 +2890,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_spacingTolerance = NULL;
+FFI_PLUGIN_EXPORT
 float get_org_apache_pdfbox_text_PDFTextStripper_spacingTolerance(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2823,6 +2899,7 @@
     return ((*jniEnv)->GetFloatField(jniEnv, self_, _f_org_apache_pdfbox_text_PDFTextStripper_spacingTolerance));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_text_PDFTextStripper_spacingTolerance(jobject self_, float value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2833,6 +2910,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_averageCharTolerance = NULL;
+FFI_PLUGIN_EXPORT
 float get_org_apache_pdfbox_text_PDFTextStripper_averageCharTolerance(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2841,6 +2919,7 @@
     return ((*jniEnv)->GetFloatField(jniEnv, self_, _f_org_apache_pdfbox_text_PDFTextStripper_averageCharTolerance));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_text_PDFTextStripper_averageCharTolerance(jobject self_, float value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2851,6 +2930,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_beadRectangles = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_text_PDFTextStripper_beadRectangles(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2859,6 +2939,7 @@
     return to_global_ref((*jniEnv)->GetObjectField(jniEnv, self_, _f_org_apache_pdfbox_text_PDFTextStripper_beadRectangles));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_text_PDFTextStripper_beadRectangles(jobject self_, jobject value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2869,6 +2950,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_charactersByArticle = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_text_PDFTextStripper_charactersByArticle(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2877,6 +2959,7 @@
     return to_global_ref((*jniEnv)->GetObjectField(jniEnv, self_, _f_org_apache_pdfbox_text_PDFTextStripper_charactersByArticle));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_text_PDFTextStripper_charactersByArticle(jobject self_, jobject value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2887,6 +2970,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_characterListMapping = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_text_PDFTextStripper_characterListMapping(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2895,6 +2979,7 @@
     return to_global_ref((*jniEnv)->GetObjectField(jniEnv, self_, _f_org_apache_pdfbox_text_PDFTextStripper_characterListMapping));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_text_PDFTextStripper_characterListMapping(jobject self_, jobject value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2905,6 +2990,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_document = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_text_PDFTextStripper_document(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2913,6 +2999,7 @@
     return to_global_ref((*jniEnv)->GetObjectField(jniEnv, self_, _f_org_apache_pdfbox_text_PDFTextStripper_document));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_text_PDFTextStripper_document(jobject self_, jobject value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2923,6 +3010,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_output = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_text_PDFTextStripper_output(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2931,6 +3019,7 @@
     return to_global_ref((*jniEnv)->GetObjectField(jniEnv, self_, _f_org_apache_pdfbox_text_PDFTextStripper_output));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_text_PDFTextStripper_output(jobject self_, jobject value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2941,6 +3030,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_inParagraph = NULL;
+FFI_PLUGIN_EXPORT
 uint8_t get_org_apache_pdfbox_text_PDFTextStripper_inParagraph(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2949,6 +3039,7 @@
     return ((*jniEnv)->GetBooleanField(jniEnv, self_, _f_org_apache_pdfbox_text_PDFTextStripper_inParagraph));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_text_PDFTextStripper_inParagraph(jobject self_, uint8_t value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2959,6 +3050,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_LIST_ITEM_EXPRESSIONS = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_text_PDFTextStripper_LIST_ITEM_EXPRESSIONS() {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2969,6 +3061,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_listOfPatterns = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_text_PDFTextStripper_listOfPatterns(jobject self_) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2977,6 +3070,7 @@
     return to_global_ref((*jniEnv)->GetObjectField(jniEnv, self_, _f_org_apache_pdfbox_text_PDFTextStripper_listOfPatterns));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_text_PDFTextStripper_listOfPatterns(jobject self_, jobject value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2987,6 +3081,7 @@
 
 
 jfieldID _f_org_apache_pdfbox_text_PDFTextStripper_MIRRORING_CHAR_MAP = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_org_apache_pdfbox_text_PDFTextStripper_MIRRORING_CHAR_MAP() {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
@@ -2995,6 +3090,7 @@
     return to_global_ref((*jniEnv)->GetStaticObjectField(jniEnv, _c_org_apache_pdfbox_text_PDFTextStripper, _f_org_apache_pdfbox_text_PDFTextStripper_MIRRORING_CHAR_MAP));
 }
 
+FFI_PLUGIN_EXPORT
 void set_org_apache_pdfbox_text_PDFTextStripper_MIRRORING_CHAR_MAP(jobject value) {
     load_env();
     load_class_gr(&_c_org_apache_pdfbox_text_PDFTextStripper, "org/apache/pdfbox/text/PDFTextStripper");
diff --git a/pkgs/jnigen/java/src/main/java/com/github/dart_lang/jnigen/apisummarizer/Main.java b/pkgs/jnigen/java/src/main/java/com/github/dart_lang/jnigen/apisummarizer/Main.java
index 4a83759..eb1d0a4 100644
--- a/pkgs/jnigen/java/src/main/java/com/github/dart_lang/jnigen/apisummarizer/Main.java
+++ b/pkgs/jnigen/java/src/main/java/com/github/dart_lang/jnigen/apisummarizer/Main.java
@@ -71,6 +71,8 @@
     if (options.addDependencies) {
       cli.add("--expand-requires=all");
     }
+    cli.addAll(List.of("-encoding", "utf8"));
+
     if (options.toolOptions != null) {
       cli.addAll(List.of(options.toolOptions.split(" ")));
     }
diff --git a/pkgs/jnigen/lib/src/bindings/c_bindings.dart b/pkgs/jnigen/lib/src/bindings/c_bindings.dart
index faadae3..dda1cd0 100644
--- a/pkgs/jnigen/lib/src/bindings/c_bindings.dart
+++ b/pkgs/jnigen/lib/src/bindings/c_bindings.dart
@@ -147,6 +147,7 @@
       final ct = isSetter ? 'void' : cType(f.type.name);
       // Getter
       final prefix = isSetter ? 'set' : 'get';
+      s.write('FFI_PLUGIN_EXPORT\n');
       s.write('$ct ${prefix}_${memberNameInC(c, fieldName)}(');
       final formalArgs = <String>[
         if (!isStatic) 'jobject self_',
diff --git a/pkgs/jnigen/lib/src/bindings/dart_bindings.dart b/pkgs/jnigen/lib/src/bindings/dart_bindings.dart
index 8495b17..20c058b 100644
--- a/pkgs/jnigen/lib/src/bindings/dart_bindings.dart
+++ b/pkgs/jnigen/lib/src/bindings/dart_bindings.dart
@@ -73,7 +73,7 @@
         s.write(_field(decl, field));
         s.writeln();
       } on SkipException catch (e) {
-        log.info('skip field ${decl.binaryName}#${field.name}: '
+        log.fine('skip field ${decl.binaryName}#${field.name}: '
             '${e.message}');
       }
     }
@@ -86,7 +86,7 @@
         s.write(_method(decl, method));
         s.writeln();
       } on SkipException catch (e) {
-        log.info('skip field ${decl.binaryName}#${method.name}: '
+        log.fine('skip field ${decl.binaryName}#${method.name}: '
             '${e.message}');
       }
     }
diff --git a/pkgs/jnigen/lib/src/generate_bindings.dart b/pkgs/jnigen/lib/src/generate_bindings.dart
index b6a64f5..c841d80 100644
--- a/pkgs/jnigen/lib/src/generate_bindings.dart
+++ b/pkgs/jnigen/lib/src/generate_bindings.dart
@@ -31,12 +31,12 @@
   final mavenDl = config.mavenDownloads;
   if (mavenDl != null) {
     final sourcePath = mavenDl.sourceDir;
-    Directory(sourcePath).create(recursive: true);
+    await Directory(sourcePath).create(recursive: true);
     await MavenTools.downloadMavenSources(
         MavenTools.deps(mavenDl.sourceDeps), sourcePath);
     extraSources.add(Uri.directory(sourcePath));
     final jarPath = mavenDl.jarDir;
-    Directory(jarPath).create(recursive: true);
+    await Directory(jarPath).create(recursive: true);
     await MavenTools.downloadMavenJars(
         MavenTools.deps(mavenDl.sourceDeps + mavenDl.jarOnlyDeps), jarPath);
     extraJars.addAll(await Directory(jarPath)
@@ -45,7 +45,6 @@
         .map((entry) => entry.uri)
         .toList());
   }
-
   final androidConfig = config.androidSdkConfig;
   if (androidConfig != null && androidConfig.addGradleDeps) {
     final deps = AndroidSdkTools.getGradleClasspaths(
diff --git a/pkgs/jnigen/lib/src/summary/summary.dart b/pkgs/jnigen/lib/src/summary/summary.dart
index 1282ee2..ab3fdcf 100644
--- a/pkgs/jnigen/lib/src/summary/summary.dart
+++ b/pkgs/jnigen/lib/src/summary/summary.dart
@@ -2,6 +2,7 @@
 // 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.
 
+import 'dart:async';
 import 'dart:io';
 import 'package:jnigen/src/logging/logging.dart';
 import 'package:jnigen/src/util/command_output.dart';
@@ -83,6 +84,7 @@
     log.info('execute $exec ${args.join(' ')}');
     final proc = await Process.start(exec, args,
         workingDirectory: workingDirectory?.toFilePath() ?? '.');
+    // ignore: unawaited_futures
     prefixedCommandOutputStream('[ApiSummarizer]', proc.stderr)
         .forEach(stderr.writeln);
     return proc.stdout;
diff --git a/pkgs/jnigen/lib/src/tools/android_sdk_tools.dart b/pkgs/jnigen/lib/src/tools/android_sdk_tools.dart
index b903bd6..72fda52 100644
--- a/pkgs/jnigen/lib/src/tools/android_sdk_tools.dart
+++ b/pkgs/jnigen/lib/src/tools/android_sdk_tools.dart
@@ -27,7 +27,7 @@
 
   static Future<String?> getAndroidSourcesPath(
       {String? sdkRoot, required List<int> versionOrder}) async {
-    final dir = _getVersionDir('sources', sdkRoot, versionOrder);
+    final dir = await _getVersionDir('sources', sdkRoot, versionOrder);
     log.info('Found sources at $dir');
     return dir;
   }
diff --git a/pkgs/jnigen/lib/src/tools/build_summarizer.dart b/pkgs/jnigen/lib/src/tools/build_summarizer.dart
index d092549..1a1033b 100644
--- a/pkgs/jnigen/lib/src/tools/build_summarizer.dart
+++ b/pkgs/jnigen/lib/src/tools/build_summarizer.dart
@@ -31,10 +31,12 @@
   ];
   log.info('execute mvn $mvnArgs');
   final mvnProc = await Process.start('mvn', mvnArgs,
-      workingDirectory: toolPath, mode: ProcessStartMode.inheritStdio);
+      workingDirectory: toolPath,
+      runInShell: true,
+      mode: ProcessStartMode.inheritStdio);
   await mvnProc.exitCode;
-  File(targetJarFile).renameSync(jarFile);
-  Directory(mvnTargetDir).deleteSync(recursive: true);
+  await File(targetJarFile).rename(jarFile);
+  await Directory(mvnTargetDir).delete(recursive: true);
 }
 
 Future<void> buildSummarizerIfNotExists({bool force = false}) async {
diff --git a/pkgs/jnigen/lib/src/tools/maven_tools.dart b/pkgs/jnigen/lib/src/tools/maven_tools.dart
index b121e39..80d2c6f 100644
--- a/pkgs/jnigen/lib/src/tools/maven_tools.dart
+++ b/pkgs/jnigen/lib/src/tools/maven_tools.dart
@@ -5,13 +5,12 @@
 import 'dart:io';
 
 import 'package:jnigen/src/logging/logging.dart';
+import 'package:path/path.dart';
 
 /// This class provides some utility methods to download a sources / jars
 /// using maven along with transitive dependencies.
 class MavenTools {
-  static const _tempPom = '__temp_pom.xml';
-  static const _tempClassPath = '__temp_classpath.xml';
-  static const _tempTarget = '__mvn_target';
+  static final currentDir = Directory(".");
 
   /// Helper method since we can't pass inheritStdio option to [Process.run].
   static Future<int> _runCmd(String exec, List<String> args,
@@ -19,19 +18,25 @@
     log.info('execute $exec ${args.join(" ")}');
     final proc = await Process.start(exec, args,
         workingDirectory: workingDirectory,
+        runInShell: true,
         mode: ProcessStartMode.inheritStdio);
     return proc.exitCode;
   }
 
   static Future<void> _runMavenCommand(
-      List<MavenDependency> deps, List<String> mvnArgs) async {
+    List<MavenDependency> deps,
+    List<String> mvnArgs,
+    Directory tempDir,
+  ) async {
     final pom = _getStubPom(deps);
+    final tempPom = join(tempDir.path, "temp_pom.xml");
+    final tempTarget = join(tempDir.path, "target");
     log.finer('using POM stub:\n$pom');
-    await File(_tempPom).writeAsString(pom);
-    await Directory(_tempTarget).create();
-    await _runCmd('mvn', ['-f', _tempPom, ...mvnArgs]);
-    await File(_tempPom).delete();
-    await Directory(_tempTarget).delete(recursive: true);
+    await File(tempPom).writeAsString(pom);
+    await Directory(tempTarget).create();
+    await _runCmd('mvn', ['-f', tempPom, ...mvnArgs]);
+    await File(tempPom).delete();
+    await Directory(tempTarget).delete(recursive: true);
   }
 
   /// Create a list of [MavenDependency] objects from maven coordinates in string form.
@@ -41,32 +46,50 @@
   /// Downloads and unpacks source files of [deps] into [targetDir].
   static Future<void> downloadMavenSources(
       List<MavenDependency> deps, String targetDir) async {
-    await _runMavenCommand(deps, [
-      'dependency:unpack-dependencies',
-      '-DexcludeTransitive=true',
-      '-DoutputDirectory=$targetDir',
-      '-Dclassifier=sources',
-    ]);
+    final tempDir = await currentDir.createTemp("maven_temp_");
+    await _runMavenCommand(
+      deps,
+      [
+        'dependency:unpack-dependencies',
+        '-DexcludeTransitive=true',
+        '-DoutputDirectory=../$targetDir',
+        '-Dclassifier=sources',
+      ],
+      tempDir,
+    );
+    await tempDir.delete(recursive: true);
   }
 
   /// Downloads JAR files of all [deps] transitively into [targetDir].
   static Future<void> downloadMavenJars(
       List<MavenDependency> deps, String targetDir) async {
-    await _runMavenCommand(deps, [
-      'dependency:copy-dependencies',
-      '-DoutputDirectory=$targetDir',
-    ]);
+    final tempDir = await currentDir.createTemp("maven_temp_");
+    await _runMavenCommand(
+      deps,
+      [
+        'dependency:copy-dependencies',
+        '-DoutputDirectory=../$targetDir',
+      ],
+      tempDir,
+    );
+    await tempDir.delete(recursive: true);
   }
 
   /// Get classpath string using JARs in maven's local repository.
   static Future<String> getMavenClassPath(List<MavenDependency> deps) async {
-    await _runMavenCommand(deps, [
-      'dependency:build-classpath',
-      '-Dmdep.outputFile=$_tempClassPath',
-    ]);
-    final classPathFile = File(_tempClassPath);
+    final tempDir = await currentDir.createTemp("maven_temp_");
+    final tempClassPath = join(tempDir.path, "maven_classpath");
+    await _runMavenCommand(
+        deps,
+        [
+          'dependency:build-classpath',
+          '-Dmdep.outputFile=$tempClassPath',
+        ],
+        tempDir);
+    final classPathFile = File(tempClassPath);
     final classpath = await classPathFile.readAsString();
     await classPathFile.delete();
+    await tempDir.delete(recursive: true);
     return classpath;
   }
 
@@ -90,7 +113,6 @@
         ${otherTags.toString()}
       </dependency>''');
     }
-
     return '''
 <project xmlns="http://maven.apache.org/POM/4.0.0"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
@@ -108,7 +130,7 @@
 ${depDecls.join("\n")}
     </dependencies>
     <build>
-      <directory>$_tempTarget</directory>
+      <directory>\${project.basedir}/target</directory>
     </build>
 </project>''';
   }
diff --git a/pkgs/jnigen/lib/src/writers/writers.dart b/pkgs/jnigen/lib/src/writers/writers.dart
index e762fee..e6e82fd 100644
--- a/pkgs/jnigen/lib/src/writers/writers.dart
+++ b/pkgs/jnigen/lib/src/writers/writers.dart
@@ -80,7 +80,7 @@
     for (var packageName in packages.keys) {
       final relativeFileName = '${packageName.replaceAll('.', '/')}.dart';
       final dartFileUri = dartRoot.resolve(relativeFileName);
-      log.info('Writing bindings for $packageName...');
+      log.fine('Writing bindings for $packageName...');
       final dartFile = await File.fromUri(dartFileUri).create(recursive: true);
       final resolver = PackagePathResolver(
           config.importMap ?? const {}, packageName, classNames,
@@ -139,7 +139,7 @@
     final packagePath = await findPackageRoot(package);
     if (packagePath != null) {
       final sourceFile = File.fromUri(packagePath.resolve(relPath));
-      final targetFile = await File.fromUri(target).create();
+      final targetFile = await File.fromUri(target).create(recursive: true);
       var source = await sourceFile.readAsString();
       if (transform != null) {
         source = transform(source);
diff --git a/pkgs/jnigen/pubspec.yaml b/pkgs/jnigen/pubspec.yaml
index 769fbff..34401ce 100644
--- a/pkgs/jnigen/pubspec.yaml
+++ b/pkgs/jnigen/pubspec.yaml
@@ -3,7 +3,7 @@
 # BSD-style license that can be found in the LICENSE file.
 
 name: jnigen
-version: 0.1.0
+version: 0.1.1
 description: Experimental generator for FFI+JNI bindings.
 repository: https://github.com/dart-lang/jnigen/tree/main/jnigen
 
diff --git a/pkgs/jnigen/test/bindings_test.dart b/pkgs/jnigen/test/bindings_test.dart
index d2b5283..7d2c3b0 100644
--- a/pkgs/jnigen/test/bindings_test.dart
+++ b/pkgs/jnigen/test/bindings_test.dart
@@ -83,6 +83,7 @@
     expect(aux.getValue(), equals(true));
     aux.setValue(false);
     expect(aux.getValue(), equals(false));
+    aux.setValue(true);
     aux.delete();
     ex.delete();
   });
diff --git a/pkgs/jnigen/test/config_test.dart b/pkgs/jnigen/test/config_test.dart
index 0c5a78e..f1ed780 100644
--- a/pkgs/jnigen/test/config_test.dart
+++ b/pkgs/jnigen/test/config_test.dart
@@ -5,6 +5,7 @@
 import 'package:jnigen/src/config/config.dart';
 import 'package:test/test.dart';
 import 'package:path/path.dart' hide equals;
+import 'package:path/path.dart' as path show equals;
 
 import 'jackson_core_test/generate.dart';
 
@@ -13,8 +14,8 @@
 final thirdParty = join(jacksonCoreTests, 'third_party');
 final lib = join(thirdParty, 'lib');
 final src = join(thirdParty, 'src');
-final testLib = join(thirdParty, 'test_lib');
-final testSrc = join(thirdParty, 'test_src');
+final testLib = join(thirdParty, 'test_', 'lib');
+final testSrc = join(thirdParty, 'test_', 'src');
 
 /// Compares 2 [Config] objects using [expect] to give useful errors when
 /// two fields are not equal.
@@ -32,9 +33,9 @@
   if (am != null) {
     expect(bm, isNotNull);
     expect(am.sourceDeps, bm!.sourceDeps);
-    expect(am.sourceDir, bm.sourceDir);
+    expect(path.equals(am.sourceDir, bm.sourceDir), isTrue);
     expect(am.jarOnlyDeps, bm.jarOnlyDeps);
-    expect(am.jarDir, bm.jarDir);
+    expect(path.equals(am.jarDir, bm.jarDir), isTrue);
   } else {
     expect(bm, isNull);
   }
@@ -69,6 +70,6 @@
   ]);
 
   test('compare configuration values', () {
-    expectConfigsAreEqual(config, getConfig(isTest: true));
+    expectConfigsAreEqual(config, getConfig(root: join(thirdParty, 'test_')));
   });
 }
diff --git a/pkgs/jnigen/test/jackson_core_test/generate.dart b/pkgs/jnigen/test/jackson_core_test/generate.dart
index 32655d5..7335757 100644
--- a/pkgs/jnigen/test/jackson_core_test/generate.dart
+++ b/pkgs/jnigen/test/jackson_core_test/generate.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:jnigen/jnigen.dart';
+import 'package:logging/logging.dart';
 import 'package:path/path.dart' hide equals;
 
 const jacksonPreamble = '// Generated from jackson-core which is licensed under'
@@ -28,7 +29,7 @@
 const deps = ['com.fasterxml.jackson.core:jackson-core:2.13.3'];
 
 Config getConfig(
-    {bool isTest = false,
+    {required String root,
     bool generateFullVersion = false,
     bool useAsm = false}) {
   final config = Config(
@@ -42,8 +43,8 @@
     ),
     preamble: jacksonPreamble,
     libraryName: testName,
-    cRoot: Uri.directory(join(thirdParty, isTest ? 'test_src' : 'src')),
-    dartRoot: Uri.directory(join(thirdParty, isTest ? 'test_lib' : 'lib')),
+    cRoot: Uri.directory(join(root, 'src')),
+    dartRoot: Uri.directory(join(root, 'lib')),
     classes: (generateFullVersion)
         ? ['com.fasterxml.jackson.core']
         : [
@@ -51,6 +52,7 @@
             'com.fasterxml.jackson.core.JsonParser',
             'com.fasterxml.jackson.core.JsonToken',
           ],
+    logLevel: Level.WARNING,
     exclude: BindingExclusions(
       fields: excludeAll<Field>([
         ['com.fasterxml.jackson.core.JsonFactory', 'DEFAULT_QUOTE_CHAR'],
@@ -64,12 +66,12 @@
 }
 
 Future<void> generate(
-    {bool isTest = false,
+    {required String root,
     bool generateFullVersion = false,
     bool useAsm = false}) async {
   final config = getConfig(
-      isTest: isTest, generateFullVersion: generateFullVersion, useAsm: useAsm);
+      root: root, generateFullVersion: generateFullVersion, useAsm: useAsm);
   await generateJniBindings(config);
 }
 
-void main() => generate(isTest: false);
+void main() => generate(root: thirdParty);
diff --git a/pkgs/jnigen/test/jackson_core_test/generated_files_test.dart b/pkgs/jnigen/test/jackson_core_test/generated_files_test.dart
index b9edc1b..c1c9185 100644
--- a/pkgs/jnigen/test/jackson_core_test/generated_files_test.dart
+++ b/pkgs/jnigen/test/jackson_core_test/generated_files_test.dart
@@ -15,17 +15,17 @@
 const testName = 'jackson_core_test';
 
 void main() async {
-  final generatedFilesRoot = join(packageTestsDir, testName, 'third_party');
-  await generate(isTest: true);
-  test("compare generated bindings for jackson_core", () {
-    compareDirs(
-        join(generatedFilesRoot, 'lib'), join(generatedFilesRoot, 'test_lib'));
-    compareDirs(
-        join(generatedFilesRoot, 'src'), join(generatedFilesRoot, 'test_src'));
+  final thirdParty = join(packageTestsDir, testName, 'third_party');
+  test("compare generated bindings for jackson_core", () async {
+    final tempDir = await Directory(thirdParty).createTemp("test_");
+    await generate(root: tempDir.path);
+
+    compareDirs(join(thirdParty, 'lib'), join(tempDir.path, "lib"));
+    compareDirs(join(thirdParty, 'src'), join(tempDir.path, "src"));
+    tempDir.deleteSync(recursive: true);
   });
-  Future<void> analyze() async {
-    final analyzeProc = await Process.start(
-        'dart', ['analyze', join('test', testName, 'third_party', 'test_lib')],
+  Future<void> analyze(String path) async {
+    final analyzeProc = await Process.start('dart', ['analyze', path],
         mode: ProcessStartMode.inheritStdio);
     final exitCode = await analyzeProc.exitCode;
     expect(exitCode, 0);
@@ -34,19 +34,15 @@
   test(
       'generate and analyze bindings for complete library, '
       'not just required classes', () async {
-    await generate(isTest: true, generateFullVersion: true);
-    await analyze();
+    final tempDir = await Directory(thirdParty).createTemp("test_");
+    await generate(root: tempDir.path, generateFullVersion: true);
+    await analyze(tempDir.path);
+    tempDir.deleteSync(recursive: true);
   }, timeout: Timeout(Duration(minutes: 2)));
   test('generate and analyze bindings using ASM', () async {
-    await generate(isTest: true, generateFullVersion: true, useAsm: true);
-    await analyze();
+    final tempDir = await Directory(thirdParty).createTemp("test_");
+    await generate(root: tempDir.path, generateFullVersion: true, useAsm: true);
+    await analyze(tempDir.path);
+    tempDir.deleteSync(recursive: true);
   }, timeout: Timeout(Duration(minutes: 2)));
-  tearDown(() async {
-    for (var dirName in ['test_lib', 'test_src']) {
-      final dir = Directory(join('test', testName, 'third_party', dirName));
-      if (await dir.exists()) {
-        await dir.delete(recursive: true);
-      }
-    }
-  });
 }
diff --git a/pkgs/jnigen/test/jackson_core_test/jnigen.yaml b/pkgs/jnigen/test/jackson_core_test/jnigen.yaml
index 96988bd..d5d7d64 100644
--- a/pkgs/jnigen/test/jackson_core_test/jnigen.yaml
+++ b/pkgs/jnigen/test/jackson_core_test/jnigen.yaml
@@ -7,6 +7,7 @@
 dart_root: test/jackson_core_test/third_party/lib
 c_root: test/jackson_core_test/third_party/src
 library_name: jackson_core_test
+log_level: warning
 classes:
   - 'com.fasterxml.jackson.core.JsonFactory'
   - 'com.fasterxml.jackson.core.JsonParser'
diff --git a/pkgs/jnigen/test/jackson_core_test/third_party/src/jackson_core_test.c b/pkgs/jnigen/test/jackson_core_test/third_party/src/jackson_core_test.c
index 6bbe92a..b77cd21 100644
--- a/pkgs/jnigen/test/jackson_core_test/third_party/src/jackson_core_test.c
+++ b/pkgs/jnigen/test/jackson_core_test/third_party/src/jackson_core_test.c
@@ -949,6 +949,7 @@
 }
 
 jfieldID _f_com_fasterxml_jackson_core_JsonFactory_DEFAULT_FACTORY_FEATURE_FLAGS = NULL;
+FFI_PLUGIN_EXPORT
 int32_t get_com_fasterxml_jackson_core_JsonFactory_DEFAULT_FACTORY_FEATURE_FLAGS() {
     load_env();
     load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
@@ -959,6 +960,7 @@
 
 
 jfieldID _f_com_fasterxml_jackson_core_JsonFactory_DEFAULT_PARSER_FEATURE_FLAGS = NULL;
+FFI_PLUGIN_EXPORT
 int32_t get_com_fasterxml_jackson_core_JsonFactory_DEFAULT_PARSER_FEATURE_FLAGS() {
     load_env();
     load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
@@ -969,6 +971,7 @@
 
 
 jfieldID _f_com_fasterxml_jackson_core_JsonFactory_DEFAULT_GENERATOR_FEATURE_FLAGS = NULL;
+FFI_PLUGIN_EXPORT
 int32_t get_com_fasterxml_jackson_core_JsonFactory_DEFAULT_GENERATOR_FEATURE_FLAGS() {
     load_env();
     load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
@@ -979,6 +982,7 @@
 
 
 jfieldID _f_com_fasterxml_jackson_core_JsonFactory_DEFAULT_ROOT_VALUE_SEPARATOR = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_com_fasterxml_jackson_core_JsonFactory_DEFAULT_ROOT_VALUE_SEPARATOR() {
     load_env();
     load_class_gr(&_c_com_fasterxml_jackson_core_JsonFactory, "com/fasterxml/jackson/core/JsonFactory");
@@ -2352,6 +2356,7 @@
 }
 
 jfieldID _f_com_fasterxml_jackson_core_JsonParser_DEFAULT_READ_CAPABILITIES = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_com_fasterxml_jackson_core_JsonParser_DEFAULT_READ_CAPABILITIES() {
     load_env();
     load_class_gr(&_c_com_fasterxml_jackson_core_JsonParser, "com/fasterxml/jackson/core/JsonParser");
diff --git a/pkgs/jnigen/test/simple_package_test/generate.dart b/pkgs/jnigen/test/simple_package_test/generate.dart
index 87906b8..67a5de0 100644
--- a/pkgs/jnigen/test/simple_package_test/generate.dart
+++ b/pkgs/jnigen/test/simple_package_test/generate.dart
@@ -4,6 +4,7 @@
 
 import 'dart:io';
 
+import 'package:logging/logging.dart';
 import 'package:path/path.dart';
 import 'package:jnigen/jnigen.dart';
 
@@ -52,6 +53,7 @@
     preamble: preamble,
     cRoot: cWrapperDir,
     dartRoot: dartWrappersRoot,
+    logLevel: Level.WARNING,
     libraryName: 'simple_package',
   );
   await generateJniBindings(config);
diff --git a/pkgs/jnigen/test/simple_package_test/src/simple_package.c b/pkgs/jnigen/test/simple_package_test/src/simple_package.c
index dc38b43..3a78ec9 100644
--- a/pkgs/jnigen/test/simple_package_test/src/simple_package.c
+++ b/pkgs/jnigen/test/simple_package_test/src/simple_package.c
@@ -107,6 +107,7 @@
 }
 
 jfieldID _f_com_github_dart_lang_jnigen_simple_package_Example_aux = NULL;
+FFI_PLUGIN_EXPORT
 jobject get_com_github_dart_lang_jnigen_simple_package_Example_aux() {
     load_env();
     load_class_gr(&_c_com_github_dart_lang_jnigen_simple_package_Example, "com/github/dart_lang/jnigen/simple_package/Example");
@@ -115,6 +116,7 @@
     return to_global_ref((*jniEnv)->GetStaticObjectField(jniEnv, _c_com_github_dart_lang_jnigen_simple_package_Example, _f_com_github_dart_lang_jnigen_simple_package_Example_aux));
 }
 
+FFI_PLUGIN_EXPORT
 void set_com_github_dart_lang_jnigen_simple_package_Example_aux(jobject value) {
     load_env();
     load_class_gr(&_c_com_github_dart_lang_jnigen_simple_package_Example, "com/github/dart_lang/jnigen/simple_package/Example");
@@ -125,6 +127,7 @@
 
 
 jfieldID _f_com_github_dart_lang_jnigen_simple_package_Example_num = NULL;
+FFI_PLUGIN_EXPORT
 int32_t get_com_github_dart_lang_jnigen_simple_package_Example_num() {
     load_env();
     load_class_gr(&_c_com_github_dart_lang_jnigen_simple_package_Example, "com/github/dart_lang/jnigen/simple_package/Example");
@@ -133,6 +136,7 @@
     return ((*jniEnv)->GetStaticIntField(jniEnv, _c_com_github_dart_lang_jnigen_simple_package_Example, _f_com_github_dart_lang_jnigen_simple_package_Example_num));
 }
 
+FFI_PLUGIN_EXPORT
 void set_com_github_dart_lang_jnigen_simple_package_Example_num(int32_t value) {
     load_env();
     load_class_gr(&_c_com_github_dart_lang_jnigen_simple_package_Example, "com/github/dart_lang/jnigen/simple_package/Example");
@@ -181,6 +185,7 @@
 }
 
 jfieldID _f_com_github_dart_lang_jnigen_simple_package_Example__Aux_value = NULL;
+FFI_PLUGIN_EXPORT
 uint8_t get_com_github_dart_lang_jnigen_simple_package_Example__Aux_value(jobject self_) {
     load_env();
     load_class_gr(&_c_com_github_dart_lang_jnigen_simple_package_Example__Aux, "com/github/dart_lang/jnigen/simple_package/Example$Aux");
@@ -189,6 +194,7 @@
     return ((*jniEnv)->GetBooleanField(jniEnv, self_, _f_com_github_dart_lang_jnigen_simple_package_Example__Aux_value));
 }
 
+FFI_PLUGIN_EXPORT
 void set_com_github_dart_lang_jnigen_simple_package_Example__Aux_value(jobject self_, uint8_t value) {
     load_env();
     load_class_gr(&_c_com_github_dart_lang_jnigen_simple_package_Example__Aux, "com/github/dart_lang/jnigen/simple_package/Example$Aux");
@@ -214,6 +220,7 @@
 }
 
 jfieldID _f_com_github_dart_lang_jnigen_pkg2_C2_CONSTANT = NULL;
+FFI_PLUGIN_EXPORT
 int32_t get_com_github_dart_lang_jnigen_pkg2_C2_CONSTANT() {
     load_env();
     load_class_gr(&_c_com_github_dart_lang_jnigen_pkg2_C2, "com/github/dart_lang/jnigen/pkg2/C2");
@@ -222,6 +229,7 @@
     return ((*jniEnv)->GetStaticIntField(jniEnv, _c_com_github_dart_lang_jnigen_pkg2_C2, _f_com_github_dart_lang_jnigen_pkg2_C2_CONSTANT));
 }
 
+FFI_PLUGIN_EXPORT
 void set_com_github_dart_lang_jnigen_pkg2_C2_CONSTANT(int32_t value) {
     load_env();
     load_class_gr(&_c_com_github_dart_lang_jnigen_pkg2_C2, "com/github/dart_lang/jnigen/pkg2/C2");
diff --git a/pkgs/jnigen/test/test_util/test_util.dart b/pkgs/jnigen/test/test_util/test_util.dart
index 7162034..ca625de 100644
--- a/pkgs/jnigen/test/test_util/test_util.dart
+++ b/pkgs/jnigen/test/test_util/test_util.dart
@@ -22,8 +22,11 @@
   return proc.exitCode;
 }
 
-Future<List<String>> getJarPaths(String testRoot) {
+Future<List<String>> getJarPaths(String testRoot) async {
   final jarPath = join(testRoot, 'jar');
+  if (!await Directory(jarPath).exists()) {
+    return [];
+  }
   return Directory(jarPath)
       .list()
       .map((entry) => entry.path)
@@ -45,6 +48,9 @@
     }
     final a = File(list1[i].path);
     final b = File(list2[i].path);
-    expect(a.readAsStringSync(), equals(b.readAsStringSync()));
+    // Some windows problems: Depending on your working tree and git config
+    // one file may have CRLFs and other may have LFs.
+    expect(a.readAsStringSync().replaceAll("\r\n", "\n"),
+        equals(b.readAsStringSync().replaceAll("\r\n", "\n")));
   }
 }
diff --git a/pkgs/jnigen/test/yaml_config_test.dart b/pkgs/jnigen/test/yaml_config_test.dart
index 330b233..0885381 100644
--- a/pkgs/jnigen/test/yaml_config_test.dart
+++ b/pkgs/jnigen/test/yaml_config_test.dart
@@ -13,23 +13,27 @@
 
 void main() {
   final thirdParty = join('test', 'jackson_core_test', 'third_party');
-  final testLib = join(thirdParty, 'test_lib');
-  final testSrc = join(thirdParty, 'test_src');
+  final testLib = join(thirdParty, 'test_lib_yaml');
+  final testSrc = join(thirdParty, 'test_src_yaml');
   final lib = join(thirdParty, 'lib');
   final src = join(thirdParty, 'src');
   final config = join('test', 'jackson_core_test', 'jnigen.yaml');
-  test('generate and compare bindings using YAML config', () {
-    final jnigenProc = Process.runSync('dart', [
-      'run',
-      'jnigen',
-      '--config',
-      config,
-      '-Dc_root=$testSrc',
-      '-Ddart_root=$testLib'
-    ]);
-    expect(jnigenProc.exitCode, equals(0));
+  test('generate and compare bindings using YAML config', () async {
+    final jnigenProc = await Process.start(
+        'dart',
+        [
+          'run',
+          'jnigen',
+          '--config',
+          config,
+          '-Dc_root=$testSrc',
+          '-Ddart_root=$testLib'
+        ],
+        mode: ProcessStartMode.inheritStdio);
+    expect(await jnigenProc.exitCode, equals(0));
 
-    final analyzeProc = Process.runSync('dart', ['analyze', testLib]);
+    final analyzeProc =
+        Process.runSync('dart', ['analyze', testLib], runInShell: true);
     expect(analyzeProc.exitCode, equals(0));
 
     compareDirs(lib, testLib);