diff --git a/.github/workflows/publish-java.yml b/.github/workflows/publish-java.yml
new file mode 100644
index 0000000..b95d06a
--- /dev/null
+++ b/.github/workflows/publish-java.yml
@@ -0,0 +1,87 @@
+name: publish-java
+
+on: workflow_dispatch
+
+permissions:
+ contents: read
+
+jobs:
+ build:
+ name: Build for ${{ matrix.target }}
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ include:
+ - target: x86_64-unknown-linux-gnu
+ os: ubuntu-latest
+ extension: so
+ - target: aarch64-unknown-linux-gnu
+ os: ubuntu-latest
+ extension: so
+ - target: x86_64-apple-darwin
+ os: macos-latest
+ extension: dylib
+ - target: aarch64-apple-darwin
+ os: macos-latest
+ extension: dylib
+ - target: x86_64-pc-windows-msvc
+ os: windows-latest
+ extension: dll
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ - uses: actions/setup-java@v4
+ with:
+ java-version: 8
+ distribution: "corretto"
+ - uses: dtolnay/rust-toolchain@stable
+ with:
+ targets: ${{ matrix.target }}
+
+ - if: ${{ matrix.target == 'aarch64-unknown-linux-gnu' }}
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
+ # Setup for cargo
+ echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc" >> $GITHUB_ENV
+
+ - run: cargo build --release --target ${{ matrix.target }} --manifest-path ./bindings/java/Cargo.toml
+ - run: mkdir -p native/${{ matrix.target }}
+ - run: mv target/${{ matrix.target }}/release/*.${{ matrix.extension }} ./native/${{ matrix.target }}/
+ - uses: actions/upload-artifact@v4
+ with:
+ name: native-libraries-${{ matrix.target }}
+ path: native/
+
+ release:
+ name: Release
+ runs-on: ubuntu-latest
+ needs: build
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ - uses: actions/setup-java@v4
+ with:
+ java-version: 8
+ distribution: "corretto"
+ server-id: ossrh
+ server-username: MAVEN_USERNAME
+ server-password: MAVEN_PASSWORD
+ - uses: actions/download-artifact@v4
+ with:
+ pattern: native-libraries-*
+ merge-multiple: true
+ path: ./bindings/java/native/
+ - run: mvn package
+ working-directory: ./bindings/java
+ - uses: actions/upload-artifact@v4
+ with:
+ name: built-jars
+ path: ./bindings/java/target/regorus-java-*.jar
+ - run: mvn deploy
+ working-directory: ./bindings/java
+ env:
+ MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }}
+ MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }}
diff --git a/bindings/java/README.md b/bindings/java/README.md
index de2f788..9c7e603 100644
--- a/bindings/java/README.md
+++ b/bindings/java/README.md
@@ -8,19 +8,38 @@
See main [Regorus page](https://github.com/microsoft/regorus) for more details about the project.
-Regorus can be used in Java via `com.microsoft.regorus` package. (It is not yet available in Maven Central, but can be manually built.)
+## Usage
-## Building
+Regorus Java is published to Maven Central with native libraries for the following:
-You can build this binding using [Maven](https://maven.apache.org/):
-```shell
-$ mvn package
-$ file target/regorus-java-0.0.1*
-target/regorus-java-0.0.1-osx-aarch_64.jar: Zip archive data, at least v1.0 to extract, compression method=deflate
-target/regorus-java-0.0.1.jar: Zip archive data, at least v1.0 to extract, compression method=deflate
+- 64-bit Linux (kernel 3.2+, glibc 2.17+)
+- ARM64 Linux (kernel 4.1, glibc 2.17+)
+- 64-bit macOS (10.12+, Sierra+)
+- ARM64 macOS (11.0+, Big Sur+)
+- 64-bit MSVC (Windows 7+)
+
+If you need to run it in a different OS or an architecture you need to manually [build it](#Building).
+
+If you're on one of the supported platforms, you can just pull prebuilt JAR from Maven Central by declaring a dependency on `com.microsoft.regorus:regorus-java`.
+
+With [Maven](https://maven.apache.org/):
+```xml
+
+
+ com.microsoft.regorus
+ regorus-java
+ 0.0.1
+
+
```
-## Usage
+With [Gradle](https://gradle.org/):
+```kotlin
+// build.gradle.kts
+implementation("com.microsoft.regorus:regorus-java:0.0.1")
+```
+
+Afterwards you can use it as follows:
```java
import com.microsoft.regorus.Engine;
@@ -28,13 +47,13 @@ import com.microsoft.regorus.Engine;
public class Test {
public static void main(String[] args) {
try (Engine engine = new Engine()) {
- engine.pubAddPolicy(
+ engine.addPolicy(
"hello.rego",
"package test\nmessage = concat(\", \", [input.message, data.message])"
);
- engine.pubAddDataJson("{\"message\":\"World!\"}");
- engine.pubSetInputJson("{\"message\":\"Hello\"}");
- String resJson = engine.pubEvalQuery("data.test.message");
+ engine.addDataJson("{\"message\":\"World!\"}");
+ engine.setInputJson("{\"message\":\"Hello\"}");
+ String resJson = engine.evalQuery("data.test.message");
System.out.println(resJson);
}
@@ -42,8 +61,37 @@ public class Test {
}
```
-and run it with:
+And you can see the following output once you run it:
```shell
-$ java -cp target/regorus-java-0.0.1.jar:target/regorus-java-0.0.1-osx-aarch_64.jar Test.java
{"result":[{"expressions":[{"value":"Hello, World!","text":"data.test.message","location":{"row":1,"col":1}}]}]}
-```
\ No newline at end of file
+```
+
+## Building
+
+In order to build Regorus Java for a target platform, you need to install Rust target
+for that target platform first:
+
+```bash
+$ rustup target add aarch64-apple-darwin
+```
+
+Afterwards, you can build native library for that target using:
+```bash
+$ cargo build --release --target aarch64-apple-darwin
+```
+
+You will then have a native library at `../../target/aarch64-apple-darwin/release/libregorus_java.dylib` depending on your target.
+
+You can then build a JAR from source using:
+```bash
+$ mvn package
+```
+
+And you will have a JAR at `./target/regorus-java-0.0.1.jar`.
+
+You need to make sure both of the artifacts in Java's classpath.
+For example with `java` CLI:
+```bash
+$ java -Djava.library.path=../../target/aarch64-apple-darwin/release/ -cp target/regorus-java-0.0.1.jar Test.java
+```
+
diff --git a/bindings/java/com_microsoft_regorus_Engine.h b/bindings/java/com_microsoft_regorus_Engine.h
index c5e1638..86f7e2f 100644
--- a/bindings/java/com_microsoft_regorus_Engine.h
+++ b/bindings/java/com_microsoft_regorus_Engine.h
@@ -9,74 +9,82 @@ extern "C" {
#endif
/*
* Class: com_microsoft_regorus_Engine
- * Method: newEngine
+ * Method: nativeNewEngine
* Signature: ()J
*/
-JNIEXPORT jlong JNICALL Java_com_microsoft_regorus_Engine_newEngine
+JNIEXPORT jlong JNICALL Java_com_microsoft_regorus_Engine_nativeNewEngine
(JNIEnv *, jclass);
/*
* Class: com_microsoft_regorus_Engine
- * Method: addPolicy
+ * Method: nativeAddPolicy
* Signature: (JLjava/lang/String;Ljava/lang/String;)V
*/
-JNIEXPORT void JNICALL Java_com_microsoft_regorus_Engine_addPolicy
+JNIEXPORT void JNICALL Java_com_microsoft_regorus_Engine_nativeAddPolicy
(JNIEnv *, jclass, jlong, jstring, jstring);
/*
* Class: com_microsoft_regorus_Engine
- * Method: addPolicyFromFile
+ * Method: nativeAddPolicyFromFile
* Signature: (JLjava/lang/String;)V
*/
-JNIEXPORT void JNICALL Java_com_microsoft_regorus_Engine_addPolicyFromFile
+JNIEXPORT void JNICALL Java_com_microsoft_regorus_Engine_nativeAddPolicyFromFile
(JNIEnv *, jclass, jlong, jstring);
/*
* Class: com_microsoft_regorus_Engine
- * Method: addDataJson
- * Signature: (JLjava/lang/String;)V
- */
-JNIEXPORT void JNICALL Java_com_microsoft_regorus_Engine_addDataJson
- (JNIEnv *, jclass, jlong, jstring);
-
-/*
- * Class: com_microsoft_regorus_Engine
- * Method: addDataJsonFromFile
- * Signature: (JLjava/lang/String;)V
- */
-JNIEXPORT void JNICALL Java_com_microsoft_regorus_Engine_addDataJsonFromFile
- (JNIEnv *, jclass, jlong, jstring);
-
-/*
- * Class: com_microsoft_regorus_Engine
- * Method: setInputJson
- * Signature: (JLjava/lang/String;)V
- */
-JNIEXPORT void JNICALL Java_com_microsoft_regorus_Engine_setInputJson
- (JNIEnv *, jclass, jlong, jstring);
-
-/*
- * Class: com_microsoft_regorus_Engine
- * Method: setInputJsonFromFile
- * Signature: (JLjava/lang/String;)V
- */
-JNIEXPORT void JNICALL Java_com_microsoft_regorus_Engine_setInputJsonFromFile
- (JNIEnv *, jclass, jlong, jstring);
-
-/*
- * Class: com_microsoft_regorus_Engine
- * Method: evalQuery
- * Signature: (JLjava/lang/String;)Ljava/lang/String;
- */
-JNIEXPORT jstring JNICALL Java_com_microsoft_regorus_Engine_evalQuery
- (JNIEnv *, jclass, jlong, jstring);
-
-/*
- * Class: com_microsoft_regorus_Engine
- * Method: destroyEngine
+ * Method: nativeClearData
* Signature: (J)V
*/
-JNIEXPORT void JNICALL Java_com_microsoft_regorus_Engine_destroyEngine
+JNIEXPORT void JNICALL Java_com_microsoft_regorus_Engine_nativeClearData
+ (JNIEnv *, jclass, jlong);
+
+/*
+ * Class: com_microsoft_regorus_Engine
+ * Method: nativeAddDataJson
+ * Signature: (JLjava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_com_microsoft_regorus_Engine_nativeAddDataJson
+ (JNIEnv *, jclass, jlong, jstring);
+
+/*
+ * Class: com_microsoft_regorus_Engine
+ * Method: nativeAddDataJsonFromFile
+ * Signature: (JLjava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_com_microsoft_regorus_Engine_nativeAddDataJsonFromFile
+ (JNIEnv *, jclass, jlong, jstring);
+
+/*
+ * Class: com_microsoft_regorus_Engine
+ * Method: nativeSetInputJson
+ * Signature: (JLjava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_com_microsoft_regorus_Engine_nativeSetInputJson
+ (JNIEnv *, jclass, jlong, jstring);
+
+/*
+ * Class: com_microsoft_regorus_Engine
+ * Method: nativeSetInputJsonFromFile
+ * Signature: (JLjava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_com_microsoft_regorus_Engine_nativeSetInputJsonFromFile
+ (JNIEnv *, jclass, jlong, jstring);
+
+/*
+ * Class: com_microsoft_regorus_Engine
+ * Method: nativeEvalQuery
+ * Signature: (JLjava/lang/String;)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_com_microsoft_regorus_Engine_nativeEvalQuery
+ (JNIEnv *, jclass, jlong, jstring);
+
+/*
+ * Class: com_microsoft_regorus_Engine
+ * Method: nativeDestroyEngine
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_com_microsoft_regorus_Engine_nativeDestroyEngine
(JNIEnv *, jclass, jlong);
#ifdef __cplusplus
diff --git a/bindings/java/pom.xml b/bindings/java/pom.xml
index f8edba5..6b5ed29 100644
--- a/bindings/java/pom.xml
+++ b/bindings/java/pom.xml
@@ -4,8 +4,7 @@
Licensed under the MIT License.
-->
-
+
4.0.0
com.microsoft.regorus
@@ -16,12 +15,27 @@
Java bindings for Regorus - a fast, lightweight Rego interpreter written in Rust
https://github.com/microsoft/regorus/bindings/java
+
+
+ MIT License
+ https://opensource.org/blog/license/mit
+
+
+
UTF-8
1.8
1.8
+
+
+ ossrh
+ Central Repository OSSRH
+ https://oss.sonatype.org/service/local/staging/deploy/maven2/
+
+
+
junit
@@ -38,114 +52,80 @@
-
-
-
- maven-clean-plugin
- 3.1.0
-
-
- maven-site-plugin
- 3.7.1
-
-
- maven-project-info-reports-plugin
- 3.0.0
-
-
-
- maven-resources-plugin
- 3.0.2
-
-
- maven-compiler-plugin
- 3.8.0
-
-
- maven-surefire-plugin
- 2.22.1
-
-
- maven-jar-plugin
- 3.0.2
-
-
- maven-install-plugin
- 2.5.2
-
-
- maven-deploy-plugin
- 2.8.2
-
-
-
+
+
+
+ ${project.basedir}/native
+
+
-
-
- kr.motd.maven
- os-maven-plugin
- 1.7.0
-
-
-
-
- exec-maven-plugin
- org.codehaus.mojo
- 3.1.0
-
-
- compile-native-code
- compile
-
- exec
-
-
- python3
-
- ${project.basedir}/tools/build.py
- --classifier
- ${os.detected.classifier}
-
-
-
-
+ exec-maven-plugin
+ org.codehaus.mojo
+ 3.1.0
+
+
+
+ build-native-lib-for-test
+ test-compile
+
+ exec
+
+
+ python3
+
+ ${project.basedir}/tools/testbuild.py
+
+
+
+
+
- org.apache.maven.plugins
- maven-surefire-plugin
- 3.1.2
+ maven-surefire-plugin
+ 3.2.5
+
+
+ -Djava.library.path=${project.basedir}/target/debug:${java.library.path}
+
+
+
- org.apache.maven.plugins
- maven-jar-plugin
-
-
-
- default-jar
-
-
- native/**
-
-
-
-
-
- native-jar
-
- jar
-
-
- ${os.detected.classifier}
-
- native/**
-
-
-
-
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 3.6.3
+
+
+ attach-javadoc
+
+ jar
+
+
+
-
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ 3.3.0
+
+
+ attach-sources
+
+ jar
+
+
+
+
+
diff --git a/bindings/java/src/lib.rs b/bindings/java/src/lib.rs
index 98ffd22..304ae71 100644
--- a/bindings/java/src/lib.rs
+++ b/bindings/java/src/lib.rs
@@ -9,7 +9,7 @@ use jni::JNIEnv;
use regorus::{Engine, Value};
#[no_mangle]
-pub extern "system" fn Java_com_microsoft_regorus_Engine_newEngine(
+pub extern "system" fn Java_com_microsoft_regorus_Engine_nativeNewEngine(
_env: JNIEnv,
_class: JClass,
) -> jlong {
@@ -18,7 +18,7 @@ pub extern "system" fn Java_com_microsoft_regorus_Engine_newEngine(
}
#[no_mangle]
-pub extern "system" fn Java_com_microsoft_regorus_Engine_addPolicy(
+pub extern "system" fn Java_com_microsoft_regorus_Engine_nativeAddPolicy(
env: JNIEnv,
_class: JClass,
engine_ptr: jlong,
@@ -35,7 +35,7 @@ pub extern "system" fn Java_com_microsoft_regorus_Engine_addPolicy(
}
#[no_mangle]
-pub extern "system" fn Java_com_microsoft_regorus_Engine_addPolicyFromFile(
+pub extern "system" fn Java_com_microsoft_regorus_Engine_nativeAddPolicyFromFile(
env: JNIEnv,
_class: JClass,
engine_ptr: jlong,
@@ -50,7 +50,20 @@ pub extern "system" fn Java_com_microsoft_regorus_Engine_addPolicyFromFile(
}
#[no_mangle]
-pub extern "system" fn Java_com_microsoft_regorus_Engine_addDataJson(
+pub extern "system" fn Java_com_microsoft_regorus_Engine_nativeClearData(
+ env: JNIEnv,
+ _class: JClass,
+ engine_ptr: jlong,
+) {
+ let _ = throw_err(env, |_env| {
+ let engine = unsafe { &mut *(engine_ptr as *mut Engine) };
+ engine.clear_data();
+ Ok(())
+ });
+}
+
+#[no_mangle]
+pub extern "system" fn Java_com_microsoft_regorus_Engine_nativeAddDataJson(
env: JNIEnv,
_class: JClass,
engine_ptr: jlong,
@@ -65,7 +78,7 @@ pub extern "system" fn Java_com_microsoft_regorus_Engine_addDataJson(
}
#[no_mangle]
-pub extern "system" fn Java_com_microsoft_regorus_Engine_addDataJsonFromFile(
+pub extern "system" fn Java_com_microsoft_regorus_Engine_nativeAddDataJsonFromFile(
env: JNIEnv,
_class: JClass,
engine_ptr: jlong,
@@ -80,7 +93,7 @@ pub extern "system" fn Java_com_microsoft_regorus_Engine_addDataJsonFromFile(
}
#[no_mangle]
-pub extern "system" fn Java_com_microsoft_regorus_Engine_setInputJson(
+pub extern "system" fn Java_com_microsoft_regorus_Engine_nativeSetInputJson(
env: JNIEnv,
_class: JClass,
engine_ptr: jlong,
@@ -95,7 +108,7 @@ pub extern "system" fn Java_com_microsoft_regorus_Engine_setInputJson(
}
#[no_mangle]
-pub extern "system" fn Java_com_microsoft_regorus_Engine_setInputJsonFromFile(
+pub extern "system" fn Java_com_microsoft_regorus_Engine_nativeSetInputJsonFromFile(
env: JNIEnv,
_class: JClass,
engine_ptr: jlong,
@@ -110,7 +123,7 @@ pub extern "system" fn Java_com_microsoft_regorus_Engine_setInputJsonFromFile(
}
#[no_mangle]
-pub extern "system" fn Java_com_microsoft_regorus_Engine_evalQuery(
+pub extern "system" fn Java_com_microsoft_regorus_Engine_nativeEvalQuery(
env: JNIEnv,
_class: JClass,
engine_ptr: jlong,
@@ -131,7 +144,7 @@ pub extern "system" fn Java_com_microsoft_regorus_Engine_evalQuery(
}
#[no_mangle]
-pub unsafe extern "system" fn Java_com_microsoft_regorus_Engine_destroyEngine(
+pub unsafe extern "system" fn Java_com_microsoft_regorus_Engine_nativeDestroyEngine(
_env: JNIEnv,
_class: JClass,
engine_ptr: jlong,
diff --git a/bindings/java/src/main/java/com/microsoft/regorus/Engine.java b/bindings/java/src/main/java/com/microsoft/regorus/Engine.java
index 17b2ed3..11fc072 100644
--- a/bindings/java/src/main/java/com/microsoft/regorus/Engine.java
+++ b/bindings/java/src/main/java/com/microsoft/regorus/Engine.java
@@ -13,77 +13,163 @@ import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.concurrent.atomic.AtomicReference;
+/**
+ * Regorus Engine.
+ */
public class Engine implements AutoCloseable {
// Methods exposed from Rust side, you can run
// `javac -h . src/main/java/com/microsoft/regorus/Engine.java` to update
// expected native header at `bindings/java/com_microsoft_regorus_Engine.h`
// if you update the native API.
- private static native long newEngine();
- private static native void addPolicy(long enginePtr, String path, String rego);
- private static native void addPolicyFromFile(long enginePtr, String path);
- private static native void addDataJson(long enginePtr, String data);
- private static native void addDataJsonFromFile(long enginePtr, String path);
- private static native void setInputJson(long enginePtr, String input);
- private static native void setInputJsonFromFile(long enginePtr, String path);
- private static native String evalQuery(long enginePtr, String query);
- private static native void destroyEngine(long enginePtr);
+ private static native long nativeNewEngine();
+ private static native void nativeAddPolicy(long enginePtr, String path, String rego);
+ private static native void nativeAddPolicyFromFile(long enginePtr, String path);
+ private static native void nativeClearData(long enginePtr);
+ private static native void nativeAddDataJson(long enginePtr, String data);
+ private static native void nativeAddDataJsonFromFile(long enginePtr, String path);
+ private static native void nativeSetInputJson(long enginePtr, String input);
+ private static native void nativeSetInputJsonFromFile(long enginePtr, String path);
+ private static native String nativeEvalQuery(long enginePtr, String query);
+ private static native void nativeDestroyEngine(long enginePtr);
// Pointer to Engine allocated on Rust's heap, all native methods works on
// engine expects this pointer. It is free'd in `close` method.
private final long enginePtr;
+ /**
+ * Creates a new Regorus Engine.
+ */
public Engine() {
- enginePtr = newEngine();
+ enginePtr = nativeNewEngine();
}
- public void pubAddPolicy(String path, String rego) {
- addPolicy(enginePtr, path, rego);
+ /**
+ * Adds an inline Rego policy.
+ *
+ * @param filename Filename of this Rego policy.
+ * @param rego Rego policy.
+ */
+ public void addPolicy(String filename, String rego) {
+ nativeAddPolicy(enginePtr, filename, rego);
}
- public void pubAddDataJson(String path) {
- addDataJson(enginePtr, path);
+ /**
+ * Adds a Rego policy from given path.
+ *
+ * @param path Path of the Rego policy.
+ */
+ public void addPolicyFromFile(String path) {
+ nativeAddPolicyFromFile(enginePtr, path);
}
- public void pubSetInputJson(String path) {
- setInputJson(enginePtr, path);
+ /**
+ * Clears the data document.
+ */
+ public void clearData() {
+ nativeClearData(enginePtr);
}
- public String pubEvalQuery(String path) {
- return evalQuery(enginePtr, path);
+ /**
+ * Adds inline data document from given JSON.
+ * The specified data document is merged into existing data document.
+ * It will throw an error if new data conflicts with the existing document.
+ *
+ * Example:
+ * addDataJson("[]") - Throws as it's not an object.
+ * addDataJson('{"a": 1}') - Fine
+ * addDataJson('{"b": 2}') - Fine, now {"a": 1, "b": 2}
+ * addDataJson('{"b": 3}') - Throws as `b` conflicts.
+ *
+ * @see clearData
+ *
+ * @throws RuntimeException If data conflicts with the existing document
+ * or data is not an object.
+ *
+ * @param data Inline data document.
+ */
+ public void addDataJson(String data) throws RuntimeException {
+ nativeAddDataJson(enginePtr, data);
+ }
+
+ /**
+ * Adds data document from given JSON file.
+ * The specified data document is merged into existing data document.
+ * It will throw an error if new data conflicts with the existing document.
+ *
+ * @see addDataJson
+ * @see clearData
+ *
+ * @throws RuntimeException If data conflicts with the existing document
+ * or data is not an object.
+ *
+ * @param path Path to JSON data document.
+ */
+ public void addDataJsonFromFile(String path) throws RuntimeException {
+ nativeAddDataJsonFromFile(enginePtr, path);
+ }
+
+ /**
+ * Sets inline JSON input.
+ *
+ * @param input inline JSON input.
+ */
+ public void setInputJson(String input) {
+ nativeSetInputJson(enginePtr, input);
+ }
+
+ /**
+ * Sets JSON input from given path.
+ *
+ * @param path Path to JSON input.
+ */
+ public void setInputJsonFromFile(String path) {
+ nativeSetInputJsonFromFile(enginePtr, path);
+ }
+
+ /**
+ * Evaluates given Rego query and returns a JSON string as a result.
+ *
+ * @param query The Rego query.
+ *
+ * @return Query results as a JSON string.
+ */
+ public String evalQuery(String query) {
+ return nativeEvalQuery(enginePtr, query);
}
@Override
public void close() {
- destroyEngine(enginePtr);
+ nativeDestroyEngine(enginePtr);
}
- // Loading native library from jar is adapted from:
+ // Loading native library from JAR is adapted from:
// https://github.com/apache/opendal/blob/93e5f65bbf30df2fed4bdd95bb0685c73c6418c2/bindings/java/src/main/java/org/apache/opendal/NativeLibrary.java
// https://github.com/apache/opendal/blob/93e5f65bbf30df2fed4bdd95bb0685c73c6418c2/bindings/java/src/main/java/org/apache/opendal/Environment.java
- private static final String classifier;
static {
- final StringBuilder classifierBuilder = new StringBuilder();
- final String os = System.getProperty("os.name").toLowerCase();
- if (os.startsWith("windows")) {
- classifierBuilder.append("windows");
- } else if (os.startsWith("mac")) {
- classifierBuilder.append("osx");
- } else {
- classifierBuilder.append("linux");
- }
- classifierBuilder.append("-");
+ // Build a Rust target triple, like: 'aarch64-unknown-linux-gnu'.
+ final StringBuilder targetTripleBuilder = new StringBuilder();
+
final String arch = System.getProperty("os.arch").toLowerCase();
if (arch.equals("aarch64")) {
- classifierBuilder.append("aarch_64");
+ targetTripleBuilder.append("aarch64");
} else {
- classifierBuilder.append("x86_64");
+ targetTripleBuilder.append("x86_64");
}
- classifier = classifierBuilder.toString();
+ targetTripleBuilder.append("-");
- loadNativeLibrary();
+ final String os = System.getProperty("os.name").toLowerCase();
+ if (os.startsWith("windows")) {
+ targetTripleBuilder.append("pc-windows-msvc");
+ } else if (os.startsWith("mac")) {
+ targetTripleBuilder.append("apple-darwin");
+ } else {
+ targetTripleBuilder.append("unknown-linux-gnu");
+ }
+
+ loadNativeLibrary(targetTripleBuilder.toString());
}
- private static void loadNativeLibrary() {
+ private static void loadNativeLibrary(String targetTriple) {
try {
// try dynamic library - the search path can be configured via "-Djava.library.path"
System.loadLibrary("regorus_java");
@@ -92,10 +178,14 @@ public class Engine implements AutoCloseable {
// ignore - try from classpath
}
- final String libraryPath = bundledLibraryPath();
+ // Native libraries will be bundles into JARs like:
+ // `aarch64-apple-darwin/libregorus_java.dylib`
+ final String libraryName = System.mapLibraryName("regorus_java");
+ final String libraryPath = "/" + targetTriple + "/" + libraryName;
+
try (final InputStream is = Engine.class.getResourceAsStream(libraryPath)) {
if (is == null) {
- throw new RuntimeException("cannot find " + libraryPath);
+ throw new RuntimeException("Cannot find " + libraryPath + "\nSee https://github.com/microsoft/regorus/tree/main/bindings/java for help.");
}
final int dot = libraryPath.indexOf('.');
final File tmpFile = File.createTempFile(libraryPath.substring(0, dot), libraryPath.substring(dot));
@@ -106,9 +196,4 @@ public class Engine implements AutoCloseable {
throw new RuntimeException(exception);
}
}
-
- private static String bundledLibraryPath() {
- final String libraryName = System.mapLibraryName("regorus_java");
- return "/native/" + classifier + "/" + libraryName;
- }
}
diff --git a/bindings/java/src/test/java/com/microsoft/regorus/EngineTest.java b/bindings/java/src/test/java/com/microsoft/regorus/EngineTest.java
index 3807e5f..ae6f7dc 100644
--- a/bindings/java/src/test/java/com/microsoft/regorus/EngineTest.java
+++ b/bindings/java/src/test/java/com/microsoft/regorus/EngineTest.java
@@ -17,13 +17,13 @@ public class EngineTest extends TestCase
{
String resJson;
try (Engine engine = new Engine()) {
- engine.pubAddPolicy(
+ engine.addPolicy(
"hello.rego",
"package test\nmessage = concat(\", \", [input.message, data.message])"
);
- engine.pubAddDataJson("{\"message\":\"World!\"}");
- engine.pubSetInputJson("{\"message\":\"Hello\"}");
- resJson = engine.pubEvalQuery("data.test.message");
+ engine.addDataJson("{\"message\":\"World!\"}");
+ engine.setInputJson("{\"message\":\"Hello\"}");
+ resJson = engine.evalQuery("data.test.message");
}
Gson gson = new Gson();
diff --git a/bindings/java/tools/build.py b/bindings/java/tools/build.py
deleted file mode 100644
index 4d2eed1..0000000
--- a/bindings/java/tools/build.py
+++ /dev/null
@@ -1,65 +0,0 @@
-#!/usr/bin/env python3
-# Copyright (c) Microsoft Corporation.
-# Licensed under the MIT License.
-#
-# This script adapted from:
-# https://github.com/apache/opendal/blob/93e5f65bbf30df2fed4bdd95bb0685c73c6418c2/bindings/java/tools/build.py
-
-from argparse import ArgumentDefaultsHelpFormatter, ArgumentParser
-from pathlib import Path
-import shutil
-import subprocess
-
-def classifier_to_target(classifier: str) -> str:
- if classifier == 'osx-aarch_64':
- return 'aarch64-apple-darwin'
- if classifier == 'osx-x86_64':
- return 'x86_64-apple-darwin'
- if classifier == 'linux-aarch_64':
- return 'aarch64-unknown-linux-gnu'
- if classifier == 'linux-x86_64':
- return 'x86_64-unknown-linux-gnu'
- if classifier == 'windows-x86_64':
- return 'x86_64-pc-windows-msvc'
- raise Exception(f'Unsupported classifier: {classifier}')
-
-def get_cargo_artifact_name(classifier: str) -> str:
- if classifier.startswith('osx'):
- return 'libregorus_java.dylib'
- if classifier.startswith('linux'):
- return 'libregorus_java.so'
- if classifier.startswith('windows'):
- return 'regorus_java.dll'
- raise Exception(f'Unsupported classifier: {classifier}')
-
-
-if __name__ == '__main__':
- basedir = Path(__file__).parent.parent
-
- parser = ArgumentParser()
- parser.add_argument('--classifier', type=str, required=True)
- args = parser.parse_args()
-
- target = classifier_to_target(args.classifier)
-
- # Setup target.
- command = ['rustup', 'target', 'add', target]
- print('$ ' + subprocess.list2cmdline(command))
- subprocess.run(command, cwd=basedir, check=True)
-
- cmd = ['cargo', 'build', '--target', target]
-
- output = basedir / 'target' / 'bindings'
- Path(output).mkdir(exist_ok=True, parents=True)
- cmd += ['--target-dir', str(output)]
-
- print('$ ' + subprocess.list2cmdline(cmd))
- subprocess.run(cmd, cwd=basedir, check=True)
-
- # History reason of cargo profiles.
- profile = 'debug'
- artifact = get_cargo_artifact_name(args.classifier)
- src = output / target / profile / artifact
- dst = basedir / 'target' / 'classes' / 'native' / args.classifier / artifact
- dst.parent.mkdir(exist_ok=True, parents=True)
- shutil.copy2(src, dst)
diff --git a/bindings/java/tools/testbuild.py b/bindings/java/tools/testbuild.py
new file mode 100644
index 0000000..088a3c8
--- /dev/null
+++ b/bindings/java/tools/testbuild.py
@@ -0,0 +1,17 @@
+#!/usr/bin/env python3
+# Copyright (c) Microsoft Corporation.
+# Licensed under the MIT License.
+#
+# Builds Regorus Java to use in Java tests. See `pom.xml`.
+
+from pathlib import Path
+import subprocess
+
+if __name__ == "__main__":
+ basedir = Path(__file__).parent.parent
+
+ output = basedir / "target"
+ Path(output).mkdir(exist_ok=True, parents=True)
+ cmd = ["cargo", "build", "--target-dir", str(output)]
+ print("$ " + subprocess.list2cmdline(cmd))
+ subprocess.run(cmd, cwd=basedir, check=True)