Skip to content

Commit 2e59a45

Browse files
authored
Added graalvm native interop example calling dart->jvm->js (#34)
2 parents 9480146 + f9fb854 commit 2e59a45

File tree

8 files changed

+155
-0
lines changed

8 files changed

+155
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,5 @@ yarn.lock
8282
!**/ios/**/default.pbxuser
8383
!**/ios/**/default.perspectivev3
8484
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
85+
/graalvm_test/build
86+
/graalvm_test_native_interop/build
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# https://dart.dev/guides/libraries/private-files
2+
# Created by `dart pub`
3+
.dart_tool/
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# GraalVM Test
2+
3+
This is a sample command-line application demonstrating how to use Dart's Java Native Interface (JNI) packages
4+
(`jni` and `jnigen`) to interoperate with Java code, specifically the GraalVM Polyglot API.
5+
6+
The application initializes a Java Virtual Machine (JVM) within a Dart environment, loads the necessary GraalVM JAR
7+
files, and then executes a simple JavaScript snippet using GraalVM's polyglot capabilities.
8+
9+
## How it Works
10+
11+
The core logic is in `bin/graalvm_test.dart`. It performs the following steps:
12+
13+
1. **Spawns a JVM**: It uses `Jni.spawn()` to start a JVM, providing the paths to the required GraalVM JAR files
14+
located in the `mvn_jar` directory.
15+
2. **Creates a Polyglot Context**: It creates a GraalVM `Context` for the JavaScript language.
16+
3. **Executes JavaScript**: It evaluates a JavaScript string that defines a simple function.
17+
4. **Interoperates**: It calls the JavaScript function from Dart, passing a string argument ("World") to it.
18+
The JavaScript code then prints a message to the console.
19+
20+
The Dart bindings for the GraalVM Polyglot API (`org.graalvm.polyglot.Context` and `org.graalvm.polyglot.Value`) are
21+
generated by `jnigen` based on the configuration in `jnigen.yaml` and the Java source files in `mvn_java`.
22+
23+
## Requirements
24+
25+
* Dart SDK
26+
* Java Development Kit (JDK) 17
27+
28+
## Setup
29+
30+
1. **Get dependencies**:
31+
```bash
32+
dart pub get
33+
```
34+
35+
2. **Generate JNI bindings**:
36+
This project uses `jnigen` to generate the Dart code for Java classes.
37+
Run the following command to generate the necessary files:
38+
```bash
39+
dart run jni:setup
40+
dart run jnigen:setup
41+
dart run jnigen --config jnigen.yaml
42+
```
43+
The underlying graalvm libraries require OpenJDK 17 or higher.
44+
45+
## Running the Application
46+
47+
After completing the setup steps, run the application with the following command:
48+
49+
```bash
50+
dart run bin/graalvm_test.dart
51+
```
52+
53+
You should see output from both Dart and the executed JavaScript code in your console.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# This file configures the static analysis results for your project (errors,
2+
# warnings, and lints).
3+
#
4+
# This enables the 'recommended' set of lints from `package:lints`.
5+
# This set helps identify many issues that may lead to problems when running
6+
# or consuming Dart code, and enforces writing Dart using a single, idiomatic
7+
# style and format.
8+
#
9+
# If you want a smaller set of lints you can change this to specify
10+
# 'package:lints/core.yaml'. These are just the most critical lints
11+
# (the recommended set includes the core lints).
12+
# The core lints are also what is used by pub.dev for scoring packages.
13+
14+
include: package:lints/recommended.yaml
15+
16+
# Uncomment the following section to specify additional rules.
17+
18+
# linter:
19+
# rules:
20+
# - camel_case_types
21+
22+
# analyzer:
23+
# exclude:
24+
# - path/to/excluded/files/**
25+
26+
# For more information about the core and recommended set of lints, see
27+
# https://dart.dev/go/core-lints
28+
29+
# For additional information about configuring this file, see
30+
# https://dart.dev/guides/language/analysis-options
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import 'package:jni/jni.dart';
2+
import 'package:path/path.dart';
3+
import 'package:graalvm_test/graal/org/graalvm/polyglot/_package.dart' as graal;
4+
5+
void main(List<String> arguments) {
6+
Jni.spawn(
7+
dylibDir: join('build', 'jni_libs'),
8+
classPath: [
9+
'./mvn_jar/collections-24.2.2.jar',
10+
'./mvn_jar/icu4j-24.2.2.jar',
11+
'./mvn_jar/jniutils-24.2.2.jar',
12+
'./mvn_jar/js-language-24.2.2.jar',
13+
'./mvn_jar/nativebridge-24.2.2.jar',
14+
'./mvn_jar/nativeimage-24.2.2.jar',
15+
'./mvn_jar/polyglot-24.2.2.jar',
16+
'./mvn_jar/regex-24.2.2.jar',
17+
'./mvn_jar/truffle-api-24.2.2.jar',
18+
'./mvn_jar/truffle-compiler-24.2.2.jar',
19+
'./mvn_jar/truffle-enterprise-24.2.2.jar',
20+
'./mvn_jar/truffle-runtime-24.2.2.jar',
21+
'./mvn_jar/word-24.2.2.jar',
22+
'./mvn_jar/xz-24.2.2.jar'
23+
],
24+
);
25+
26+
var jsCode = "(function myFun(param){console.log('Hello ' + param + ' from JS');})";
27+
28+
var langs = JArray.of(JString.type, ["js".toJString()]);
29+
var context = graal.Context.create(langs);
30+
var value = context?.eval$1("js".toJString(), jsCode.toJString());
31+
print(value);
32+
value?.execute(JArray.of(JString.type, ["World".toJString()]));
33+
return;
34+
}
35+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
output:
2+
dart:
3+
path: lib/graal/
4+
5+
classes:
6+
- 'org.graalvm.polyglot.Context'
7+
- 'org.graalvm.polyglot.Value'
8+
9+
maven_downloads:
10+
jar_only_deps:
11+
- 'org.graalvm.polyglot:polyglot:24.2.1'
12+
- 'org.graalvm.polyglot:js:24.2.2'
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
int calculate() {
2+
return 6 * 7;
3+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
name: graalvm_test
2+
description: A sample command-line application.
3+
version: 1.0.0
4+
# repository: https://github.com/my_org/my_repo
5+
6+
environment:
7+
sdk: ^3.10.0-36.0.dev
8+
9+
# Add regular dependencies here.
10+
dependencies:
11+
path: ^1.9.0
12+
jni: ^0.14.2
13+
jnigen: ^0.14.2
14+
15+
dev_dependencies:
16+
lints: ^6.0.0
17+
test: ^1.25.6

0 commit comments

Comments
 (0)