Fix Java library

This commit is contained in:
Wilson Lin 2020-01-18 17:55:13 +11:00
parent 36eb03af64
commit 542f9fcf3f
7 changed files with 112 additions and 42 deletions

1
java/.gitignore vendored
View File

@ -1,2 +1,3 @@
/Cargo.lock
/target
/src/main/resources/*.nativelib

View File

@ -10,4 +10,4 @@ jni = "0.14.0"
[lib]
crate-type = ["cdylib"]
path = "src/main/rust/src/lib.rs"
path = "src/main/rust/lib.rs"

50
java/build.sh Executable file
View File

@ -0,0 +1,50 @@
#!/usr/bin/env bash
set -e
# Builds hyperbuild-java with native module for local testing.
# Built JAR will only run current platform.
pushd "$(dirname "$0")"
if [ "$1" = "release" ]; then
rust_build_arg="--release"
rust_build_dir="release"
else
rust_build_arg=""
rust_build_dir="debug"
fi
if [[ "$OSTYPE" == "linux-gnu" ]]; then
os_name="linux"
ext="so"
elif [[ "$OSTYPE" == "darwin"* ]]; then
os_name="macos"
ext="dylib"
elif [[ "$OSTYPE" == "cygwin" ]]; then
os_name="windows"
ext="dll"
elif [[ "$OSTYPE" == "msys" ]]; then
os_name="windows"
ext="dll"
elif [[ "$OSTYPE" == "win32" ]]; then
os_name="windows"
ext="dll"
else
echo "Unknown OS"
exit 1
fi
if [ -f Cargo.toml.orig ]; then
echo 'Not altering Java Cargo.toml file'
else
cp Cargo.toml Cargo.toml.orig
fi
sed -i 's%^hyperbuild = .*$%hyperbuild = { path = ".." }%' Cargo.toml
cargo build $rust_build_arg
mv Cargo.toml.orig Cargo.toml
cp target/rust/$rust_build_dir/libhyperbuild_java.$ext src/main/resources/$os_name-x86_64.nativelib
mvn clean package
popd

View File

@ -1,10 +1,9 @@
package in.wilsonl.hyperbuild;
import java.util.Arrays;
import java.nio.ByteBuffer;
import static in.wilsonl.hyperbuild.NativeLibraryLoader.loadLibraryFromJar;
import static java.lang.String.format;
import static java.nio.charset.StandardCharsets.UTF_8;
public class Hyperbuild {
static {
@ -25,20 +24,13 @@ public class Hyperbuild {
}
try {
loadLibraryFromJar(format("%s-%s.nativelib", nativeLibNameOs, nativeLibNameArch));
loadLibraryFromJar(format("/%s-%s.nativelib", nativeLibNameOs, nativeLibNameArch));
} catch (Exception e) {
throw new RuntimeException("Failed to load native library", e);
}
}
public static native int minifyInPlace(byte[] code) throws HyperbuildException;
public static native int minifyInPlace(ByteBuffer code) throws HyperbuildException;
public static byte[] minify(byte[] code) throws HyperbuildException {
int size = minifyInPlace(code);
return Arrays.copyOf(code, size);
}
public static String minify(String code) throws HyperbuildException {
return new String(Hyperbuild.minify(code.getBytes(UTF_8)), UTF_8);
}
public static native String minify(String code) throws HyperbuildException;
}

View File

@ -34,16 +34,14 @@ import java.nio.file.Files;
import java.nio.file.ProviderNotFoundException;
import java.nio.file.StandardCopyOption;
import static java.lang.String.format;
public class NativeLibraryLoader {
private NativeLibraryLoader() {
}
public static void loadLibraryFromJar(String filename) throws IOException {
File temp = File.createTempFile("hyperbuild-java-nativelib", filename);
File temp = File.createTempFile("hyperbuild-java-nativelib", filename.substring(1));
try (InputStream is = NativeLibraryLoader.class.getResourceAsStream(format("/%s", filename))) {
try (InputStream is = NativeLibraryLoader.class.getResourceAsStream(filename)) {
Files.copy(is, temp.toPath(), StandardCopyOption.REPLACE_EXISTING);
System.load(temp.getAbsolutePath());
} finally {

54
java/src/main/rust/lib.rs Normal file
View File

@ -0,0 +1,54 @@
use hyperbuild::hyperbuild;
use jni::JNIEnv;
use jni::objects::{JByteBuffer, JClass, JObject, JString};
use jni::sys::{jint, jstring};
use std::str::from_utf8_unchecked;
#[no_mangle]
pub extern "system" fn Java_in_wilsonl_hyperbuild_Hyperbuild_minifyInPlace(
env: JNIEnv,
_class: JClass,
input: JByteBuffer,
)
-> jint {
let source = match env.get_direct_buffer_address(input) {
Ok(ptr) => ptr,
Err(_) => {
env.throw_new("java/lang/IllegalArgumentException", "ByteBuffer is not direct").unwrap();
return 0;
}
};
(match hyperbuild(source) {
Ok(out_len) => out_len,
Err((err, pos)) => {
env.throw_new(
"in/wilsonl/hyperbuild/HyperbuildException",
format!("{} [Character {}]", err.message(), pos),
).unwrap();
0
}
}) as jint
}
#[no_mangle]
pub extern "system" fn Java_in_wilsonl_hyperbuild_Hyperbuild_minify(
env: JNIEnv,
_class: JClass,
input: JString,
)
-> jstring {
let source: String = env.get_string(input).unwrap().into();
let mut code = source.as_bytes().to_vec();
match hyperbuild(&mut code) {
Ok(out_len) => env.new_string(unsafe { from_utf8_unchecked(&code[0..out_len]) }).unwrap().into_inner(),
Err((err, pos)) => {
env.throw_new(
"in/wilsonl/hyperbuild/HyperbuildException",
format!("{} [Character {}]", err.message(), pos),
).unwrap();
JObject::null().into_inner()
}
}
}

View File

@ -1,25 +0,0 @@
use hyperbuild::hyperbuild;
use jni::JNIEnv;
use jni::objects::JClass;
use jni::sys::{jbyteArray, jint};
#[no_mangle]
pub extern "system" fn Java_in_wilsonl_hyperbuild_Hyperbuild_minifyInPlace(
env: JNIEnv,
_class: JClass,
input: jbyteArray,
)
-> jint {
let source = &mut env.convert_byte_array(input).unwrap();
(match hyperbuild(source) {
Ok(out_len) => out_len,
Err((err, pos)) => {
env.throw_new(
"in/wilsonl/hyperbuild/HyperbuildException",
format!("{} [Character {}]", err.message(), pos),
).unwrap();
0
}
}) as jint
}