dart-lang / native

Dart packages related to FFI and native assets bundling.
BSD 3-Clause "New" or "Revised" License
105 stars 36 forks source link

Support reading source JARs #661

Closed mahesh-hegde closed 1 year ago

mahesh-hegde commented 1 year ago

summarizer can read

Source JARs are currently a notable omission.

This is small implementation detail - because we need to pass a JavaFileObject to DocletSummarizer. But we can subclass SimpleJavaFileObject to refer to a {JarFile, ZipEntry} pair.

Follow up question:

While we are at it, should default maven source download format be changed from unpack-dependencies (scatters all source files in package layout) to copy-dependencies (just copies the JARs, similar to what we do with compiled JARs)?

cah-aamir commented 1 year ago

Does it support generating bindings for jar files containing compiled .class files read from local memory? I'm trying to run ffigen on a 3rd party jar file that is not available on maven and seems like it can't find any classes. When I extract the jar I do see all the compiled .class files. I use the class_path and classes option in the config file.

mahesh-hegde commented 1 year ago

Does it support generating bindings for jar files containing compiled .class files read from local memory?

Yes.

What's the error? This shouldn't happen. It's great if you can share config too.

mahesh-hegde commented 1 year ago

This may be an instance of dart-lang/native#714.

Will be pushing a fix soon.

Until then, try giving a dummy source path eg an empty dir.

Or using backend: asm option (refer README).

cah-aamir commented 1 year ago

Does it support generating bindings for jar files containing compiled .class files read from local memory?

Yes.

What's the error? This shouldn't happen. It's great if you can share config too.

Looks like I'm missing something in the config. My jar file is in sdk folder (sdk/jackson-core-2.13.4.jar) and here's the config: (Also, it's the same jar from the example that downloads it from maven)

output:
  c:
    library_name: example
    path: src/example/
  dart:
    path: lib/example.dart
    structure: single_file

class_path:
  - 'sdk/'

classes:
  - 'com.fasterxml.jackson.core.JsonFactory'

Error message:

(jnigen) INFO: ApiSummarizer.jar exists. Skipping build..
(jnigen) INFO: execute java -jar .dart_tool/jnigen/ApiSummarizer.jar -s com/fasterxml/jackson/core/JsonFactory -c sdk/ com.fasterxml.jackson.core.JsonFactory
Not found: [com.fasterxml.jackson.core.JsonFactory]

Fatal: Cannot parse summary: FormatException: Unexpected end of input (at character 1)

Also tried to add the class_path as follows but same error:

source_path:
  - 'com/fasterxml/jackson/core/'
mahesh-hegde commented 1 year ago

You should give file path of JAR itself. (Because JAR is kind of like compressed folder).

Also use backend: asm. Refer end of README for more details. Detection should be automatic, but dart-lang/native#714 is yet to be fixed.

    Mahesh

On Fri, 31 Mar, 2023, 7:02 pm cah-aamir, @.***> wrote:

Does it support generating bindings for jar files containing compiled .class files read from local memory?

Yes.

What's the error? This shouldn't happen. It's great if you can share config too.

Looks like I'm missing something in the config. My jar file is in sdk folder (sdk/jackson-core-2.13.4.jar) and here's the config:

output: c: library_name: example path: src/example/ dart: path: lib/example.dart structure: single_file

class_path:

  • 'sdk/'

classes:

  • 'com.fasterxml.jackson.core.JsonFactory'

Error message:

(jnigen) INFO: ApiSummarizer.jar exists. Skipping build.. (jnigen) INFO: execute java -jar .dart_tool/jnigen/ApiSummarizer.jar -s com/fasterxml/jackson/core/JsonFactory -c sdk/ com.fasterxml.jackson.core.JsonFactory Not found: [com.fasterxml.jackson.core.JsonFactory]

Fatal: Cannot parse summary: FormatException: Unexpected end of input (at character 1)

— Reply to this email directly, view it on GitHub https://github.com/dart-lang/native/issues/661, or unsubscribe https://github.com/notifications/unsubscribe-auth/ALAKLFXOZILVQA7GAVLPYRLW63MIRANCNFSM6AAAAAAWH4UGOE . You are receiving this because you authored the thread.Message ID: @.***>

mahesh-hegde commented 1 year ago

Try these changes.

class_path:
    - 'sdk/jackson-core-2.13.4.jar'
summarizer:
    backend: asm
cah-aamir commented 1 year ago
summarizer:
    backend: asm

Thanks, that got it working. I had tried the actual path of jar also but seems like it wasn't working because of the missing summarizer backend config.

mahesh-hegde commented 1 year ago

Thanks for reminding me of this. I will be soon pushing a fix to this.

cah-aamir commented 1 year ago

I did get the bindings generated and I think I have it all in place, I keep getting the following error, seems like it can't find the classes:

I/gen_app_example(24594): Compiler allocated 4579KB to compile void android.view.ViewRootImpl.performTraversals()
F/gen_app_example(24594): java_vm_ext.cc:594] JNI DETECTED ERROR IN APPLICATION: JNI NewGlobalRef called with pending exception java.lang.ClassNotFoundException: Didn't find class "com/fasterxml/jackson/core/JsonFactory" on path: DexPathList[[zip file "/data/app/~~Um4goRBmimcwQ0EnjPl8Ng==/com.example.jnigen_app_example-ZCvGTHesXgtSQXT0Zv5a5g==/base.apk"],nativeLibraryDirectories=[/data/app/~~Um4goRBmimcwQ0EnjPl8Ng==/com.example.jnigen_app_example-ZCvGTHesXgtSQXT0Zv5a5g==/lib/arm64, /data/app/~~Um4goRBmimcwQ0EnjPl8Ng==/com.example.jnigen_app_example-ZCvGTHesXgtSQXT0Zv5a5g==/base.apk!/lib/arm64-v8a, /system/lib64, /system_ext/lib64]]
F/gen_app_example(24594): java_vm_ext.cc:594]   at java.lang.Class dalvik.system.BaseDexClassLoader.findClass(java.lang.String) (BaseDexClassLoader.java:259)
F/gen_app_example(24594): java_vm_ext.cc:594]   at java.lang.Class java.lang.ClassLoader.loadClass(java.lang.String, boolean) (ClassLoader.java:379)
F/gen_app_example(24594): java_vm_ext.cc:594]   at java.lang.Class java.lang.ClassLoader.loadClass(java.lang.String) (ClassLoader.java:312)
F/gen_app_example(24594): java_vm_ext.cc:594]
F/gen_app_example(24594): java_vm_ext.cc:594]     in call to NewGlobalRef
F/gen_app_example(24594): runtime.cc:681] Runtime aborting...

Here is my source code, I'm trying it in a new FFI plugin project, using the jackson-core jar and trying to invoke builder in main.dart. Seems like I'm missing something: https://github.com/cah-aamir/jnigen_app

mahesh-hegde commented 1 year ago

You have to get the classes into Android project. jnigen (currently) cannot help with that.

You should add the JAR to android apps gradle dependencies. (file or fileTree)

and add -keep rules for required classes (or shortcut: all classes) in proguard-rules.pro file. (Otherwise proguard will prune the classes it deems unused).

cah-aamir commented 1 year ago

Jackson-core from the example worked fine, but for the actual library that I'm trying to use in my app it was throwing *.so file missing exception. After adding the .so files to the app I was finally able to call one of methods within the library without any exception. This is great, saves us the time/effort to write the conventional flutter plugin from scratch, unless we hit any other roadblocks. Will be trying ffigen next.