Project Queries: JNI interop with Dart

127 views
Skip to first unread message

Prayas Kumar Singh

unread,
Apr 15, 2022, 4:24:02 PM4/15/22
to dart-gsoc
Dear Mentors
Greetings of the day.

I am Prayas, a student at Birla Institute of Technology and Sciences, Pilani. I am interested in the GSoC project - JNI interop for Dart. I know there is a discussion forum. I even put some queries there before. I have made my heart and mind to work this summer with Dart 🤞🏻. Hopefully, also in the fall. The project really excites me. The last few days, reading and researching the task, related projects, building the sample project and preparing possible workflows for the project have been such a fun and delightful experience. I can not wait for summer to begin and get on with it.

I am writing this mail to discuss ideas that may be within or beyond the project's scope but are strongly related to the project. And to take your opinions on it.
  1. DartVM, JVM and Garbage collection: 
    • When to collect garbage? How to coordinate it between the two VMs? What will happen if both VMs work asynchronously on the same data in a heap?
    • How do you detect cycles between the VMs?
      •  How I imagine it is as DartVM will exist throughout the running of an app. JVM will be booted when DartVM calls JVM and then shuts down. 
  2. Memory debugging tools: In continuation with the previous point, should the package I write will also provide memory debugging tools? If so, what technical depths will that be expected? 
  3. C is a procedural lang, and Dart and Java are object-oriented langs.
    1. dart:ffigen generates dart bindings for C libraries. It converts Dart primitive data types int, double, etc to C primitive data types like int32, int64, char, bool, etc for native functions in C. But Java libraries can also have functions with objects as parameters. Developers of Dart will like features where Java Classes will map/bind to Dart Classes with as little code as possible. eg: DartParentClass binds to JavaParentClass, DartChildClassA binds to JavaChildClassA, and so on with as little code as possible. (Refer to the image below) 
    2. Implementing polymorphism is the trickiest and most mind-boggling (refer to image) task I can think of. Say Dart Class Files are generated using Java Class Files and binded to Java Class Files. Next, MAIN.dart has an object called objVar of type DartParentClass, storing an object of DartChildClassA later DartChildClassB. The commands at line2 and line4 are to call the java functions using JNI from the dart code. The function call at line2 should pick f1, not f2. Similarly, line4 should call f2, not f1. I cannot process this out, but I am sure I can reach an algorithmic conclusion.
UML class-2.png

As of now, points 1 and 2 are optional deliverables, i.e. if I get the extended timeline. 
Point 3, in my opinion, is very much needed. Without this, the project will be incomplete.
I require your thoughts and opinions on all 3.

Also, currently, I am still working on my proposal, refining workflow, mapping the timeline, etc. Most of all waiting for your input. Then I will submit a draft for you to review.

Sincerely
Prayas Kumar Singh

Mahesh Hegde

unread,
Apr 16, 2022, 4:16:21 AM4/16/22
to dart-gsoc
PS: Not a mentor. I am another student.

> How I imagine it is as DartVM will exist throughout the running of an app. JVM will be booted when DartVM calls JVM and then shuts down. 

That's not how it works. If you have finished writing sample code, you will observe that you load the native library from Java, and native code gets reference to Java VM.

> C is a procedural lang, and Dart and Java are object-oriented langs

An object orient lang is a procedural lang with vtable :xD

> I require your thoughts and opinions on all 3.

I am not sure I follow, you can override methods in dart classes just like you can do in Java. I don't think this will be a big problem.

On java objects, you are always invoking the overridden method, unless you use CallNonVirtualMethod family of functions.
Message has been deleted
Message has been deleted
Message has been deleted
Message has been deleted

dacoharkes

unread,
Apr 19, 2022, 3:15:06 AM4/19/22
to dart-gsoc
Hi Prayas,

See my answers below.

Kind regards,

Daco

On Friday, April 15, 2022 at 10:24:02 PM UTC+2 f201...@goa.bits-pilani.ac.in wrote:
Dear Mentors
Greetings of the day.

I am Prayas, a student at Birla Institute of Technology and Sciences, Pilani. I am interested in the GSoC project - JNI interop for Dart. I know there is a discussion forum. I even put some queries there before. I have made my heart and mind to work this summer with Dart 🤞🏻. Hopefully, also in the fall. The project really excites me. The last few days, reading and researching the task, related projects, building the sample project and preparing possible workflows for the project have been such a fun and delightful experience. I can not wait for summer to begin and get on with it.

I am writing this mail to discuss ideas that may be within or beyond the project's scope but are strongly related to the project. And to take your opinions on it.
  1. DartVM, JVM and Garbage collection: 
    • When to collect garbage? How to coordinate it between the two VMs? What will happen if both VMs work asynchronously on the same data in a heap?
Both VMs have their own heap with their own GC. Theoretically this might create the problem that one of the two GCs doesn't feel the need to run but that heap holding on to objects from the other heap.
The only way to hold on to Java or Dart objects from outside their heap is with handles. So we might be able to detect something fishy going on.
So far, we haven't run into issues.
(Fun fact: in JavaScript the heap is shared with the browser DOM, precisely to avoid this issue.) 
    • How do you detect cycles between the VMs?
      •  How I imagine it is as DartVM will exist throughout the running of an app. JVM will be booted when DartVM calls JVM and then shuts down. 
For a single run script on the desktop I'd indeed image starting the DartVM first, and then running the JVM through the JNI interface.
So for a standalone Dart app you can manage the JVM lifecycle yourself.

For Flutter apps on Android, the JVM is started first, and then the DartVM. Both will run until the app is shutdown. 
So for a Flutter app you don't have to think about the life cycle.
  1. Memory debugging tools: In continuation with the previous point, should the package I write will also provide memory debugging tools? If so, what technical depths will that be expected? 
I'd say that is a separate project.

You can debug C memory by running gdb/lldb on the dart executable when running Dart in standalone mode. (And still access the Dart memory with devtools/observatory.) 
  1. C is a procedural lang, and Dart and Java are object-oriented langs.
    1. dart:ffigen generates dart bindings for C libraries. It converts Dart primitive data types int, double, etc to C primitive data types like int32, int64, char, bool, etc for native functions in C. But Java libraries can also have functions with objects as parameters.
C can hold on to objects from Dart with Handle and C can hold on to objects from Java jobject.
When wrapping a Java object and exposing in Dart we could have a Dart class that contains a Pointer<jobject>, and then when a method is called on the Dart object, call the C method with the Pointer<jobject> and other arguments, and invoke the right JNI code to call the Java method.
    1. Developers of Dart will like features where Java Classes will map/bind to Dart Classes with as little code as possible. eg: DartParentClass binds to JavaParentClass, DartChildClassA binds to JavaChildClassA, and so on with as little code as possible. (Refer to the image below) 
I would imagine dynamic dispatch just works. E.g. you could just expose the method on the super class and always call that. 
    1. Implementing polymorphism is the trickiest and most mind-boggling (refer to image) task I can think of. Say Dart Class Files are generated using Java Class Files and binded to Java Class Files. Next, MAIN.dart has an object called objVar of type DartParentClass, storing an object of DartChildClassA later DartChildClassB. The commands at line2 and line4 are to call the java functions using JNI from the dart code. The function call at line2 should pick f1, not f2. Similarly, line4 should call f2, not f1. I cannot process this out, but I am sure I can reach an algorithmic conclusion.
Doesn't JNI just call the right method based on the `this`?

dacoharkes

unread,
Apr 19, 2022, 3:23:06 AM4/19/22
to dart-gsoc
Hi Prayas,

> How do you detect cycles between the VMs?

If we end up in the situation where we have cycles, we would usually have a WeakReference one way to break the cycle.

Though, I expect that if we wrap Java objects in a Dart API, all pointers will be from Dart to Java, not the other way around.

Kind regards,

Daco
Reply all
Reply to author
Forward
0 new messages