Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,5 @@ yarn.lock
!**/ios/**/default.pbxuser
!**/ios/**/default.perspectivev3
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
/graalvm_test/build
/graalvm_test_native_interop/build
3 changes: 3 additions & 0 deletions graalvm_test_native_interop/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# https://dart.dev/guides/libraries/private-files
# Created by `dart pub`
.dart_tool/
53 changes: 53 additions & 0 deletions graalvm_test_native_interop/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# GraalVM Test

This is a sample command-line application demonstrating how to use Dart's Java Native Interface (JNI) packages
(`jni` and `jnigen`) to interoperate with Java code, specifically the GraalVM Polyglot API.

The application initializes a Java Virtual Machine (JVM) within a Dart environment, loads the necessary GraalVM JAR
files, and then executes a simple JavaScript snippet using GraalVM's polyglot capabilities.

## How it Works

The core logic is in `bin/graalvm_test.dart`. It performs the following steps:

1. **Spawns a JVM**: It uses `Jni.spawn()` to start a JVM, providing the paths to the required GraalVM JAR files
located in the `mvn_jar` directory.
2. **Creates a Polyglot Context**: It creates a GraalVM `Context` for the JavaScript language.
3. **Executes JavaScript**: It evaluates a JavaScript string that defines a simple function.
4. **Interoperates**: It calls the JavaScript function from Dart, passing a string argument ("World") to it.
The JavaScript code then prints a message to the console.

The Dart bindings for the GraalVM Polyglot API (`org.graalvm.polyglot.Context` and `org.graalvm.polyglot.Value`) are
generated by `jnigen` based on the configuration in `jnigen.yaml` and the Java source files in `mvn_java`.

## Requirements

* Dart SDK
* Java Development Kit (JDK) 17

## Setup

1. **Get dependencies**:
```bash
dart pub get
```

2. **Generate JNI bindings**:
This project uses `jnigen` to generate the Dart code for Java classes.
Run the following command to generate the necessary files:
```bash
dart run jni:setup
dart run jnigen:setup
dart run jnigen --config jnigen.yaml
```
The underlying graalvm libraries require OpenJDK 17 or higher.

## Running the Application

After completing the setup steps, run the application with the following command:

```bash
dart run bin/graalvm_test.dart
```

You should see output from both Dart and the executed JavaScript code in your console.
30 changes: 30 additions & 0 deletions graalvm_test_native_interop/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# This file configures the static analysis results for your project (errors,
# warnings, and lints).
#
# This enables the 'recommended' set of lints from `package:lints`.
# This set helps identify many issues that may lead to problems when running
# or consuming Dart code, and enforces writing Dart using a single, idiomatic
# style and format.
#
# If you want a smaller set of lints you can change this to specify
# 'package:lints/core.yaml'. These are just the most critical lints
# (the recommended set includes the core lints).
# The core lints are also what is used by pub.dev for scoring packages.

include: package:lints/recommended.yaml

# Uncomment the following section to specify additional rules.

# linter:
# rules:
# - camel_case_types

# analyzer:
# exclude:
# - path/to/excluded/files/**

# For more information about the core and recommended set of lints, see
# https://dart.dev/go/core-lints

# For additional information about configuring this file, see
# https://dart.dev/guides/language/analysis-options
35 changes: 35 additions & 0 deletions graalvm_test_native_interop/bin/graalvm_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import 'package:jni/jni.dart';
import 'package:path/path.dart';
import 'package:graalvm_test/graal/org/graalvm/polyglot/_package.dart' as graal;

void main(List<String> arguments) {
Jni.spawn(
dylibDir: join('build', 'jni_libs'),
classPath: [
'./mvn_jar/collections-24.2.2.jar',
'./mvn_jar/icu4j-24.2.2.jar',
'./mvn_jar/jniutils-24.2.2.jar',
'./mvn_jar/js-language-24.2.2.jar',
'./mvn_jar/nativebridge-24.2.2.jar',
'./mvn_jar/nativeimage-24.2.2.jar',
'./mvn_jar/polyglot-24.2.2.jar',
'./mvn_jar/regex-24.2.2.jar',
'./mvn_jar/truffle-api-24.2.2.jar',
'./mvn_jar/truffle-compiler-24.2.2.jar',
'./mvn_jar/truffle-enterprise-24.2.2.jar',
'./mvn_jar/truffle-runtime-24.2.2.jar',
'./mvn_jar/word-24.2.2.jar',
'./mvn_jar/xz-24.2.2.jar'
],
);

var jsCode = "(function myFun(param){console.log('Hello ' + param + ' from JS');})";

var langs = JArray.of(JString.type, ["js".toJString()]);
var context = graal.Context.create(langs);
var value = context?.eval$1("js".toJString(), jsCode.toJString());
print(value);
value?.execute(JArray.of(JString.type, ["World".toJString()]));
return;
}

12 changes: 12 additions & 0 deletions graalvm_test_native_interop/jnigen.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
output:
dart:
path: lib/graal/

classes:
- 'org.graalvm.polyglot.Context'
- 'org.graalvm.polyglot.Value'

maven_downloads:
jar_only_deps:
- 'org.graalvm.polyglot:polyglot:24.2.1'
- 'org.graalvm.polyglot:js:24.2.2'
3 changes: 3 additions & 0 deletions graalvm_test_native_interop/lib/graalvm_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
int calculate() {
return 6 * 7;
}
17 changes: 17 additions & 0 deletions graalvm_test_native_interop/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: graalvm_test
description: A sample command-line application.
version: 1.0.0
# repository: https://github.com/my_org/my_repo

environment:
sdk: ^3.10.0-36.0.dev

# Add regular dependencies here.
dependencies:
path: ^1.9.0
jni: ^0.14.2
jnigen: ^0.14.2

dev_dependencies:
lints: ^6.0.0
test: ^1.25.6
Loading