M README.md +3 -3
@@ 3,11 3,11 @@ WofiJ is a Java API for Wofi
## Dependencies
wofi
- openjdk-11-jdk
- pkg-config
+ openjdk-17-jdk
+ pkgconf
meson
## Building
hg clone https://hg.sr.ht/~scoopta/WofiJ
cd WofiJ/src
- meson -Djdk_home=$JAVA_HOME -Dmode_class=org/example/MyMode ../build
+ meson -Djdk_home=$JAVA_HOME -Dwofij_path=/path/to/wofij.jar -Dmode_class=com.example.my_mode/com.example.my_mode.Main -Dmode_path=/path/to/my/mode.jar ../build
ninja -C ../build
M src/meson.build +7 -6
@@ 5,13 5,13 @@ wofi = dependency('wofi')
pixbuf = dependency('gdk-pixbuf-2.0')
java_home = get_option('jdk_home')
+wofij_path = get_option('wofij_path')
mode_class = get_option('mode_class')
-class_path = get_option('class_path')
-add_project_arguments('-DMODE_CLASS="' + mode_class + '"', language : 'c')
+mode_path = get_option('mode_path')
-if class_path != ''
- add_project_arguments('-DCLASS_PATH="' + class_path + '"', language : 'c')
-endif
+add_project_arguments('-DMODULE_PATH="' + wofij_path + '"', language : 'c')
+add_project_arguments('-DMODE_CLASS="' + mode_class + '"', language : 'c')
+add_project_arguments('-DMODE_PATH="' + mode_path + '"', language : 'c')
jvm = cc.find_library('jvm', dirs : [java_home + '/lib/j9vm', java_home + '/lib/server'])
@@ 23,7 23,8 @@ inc = include_directories('../wofi_jni/i
deps = [wofi, jvm, pixbuf]
-jsources = [jsrcdir + '/Cache.java',
+jsources = ['module-info.java',
+ jsrcdir + '/Cache.java',
jsrcdir + '/Map.java',
jsrcdir + '/Mode.java',
jsrcdir + '/Widget.java',
M src/meson_options.txt +2 -1
@@ 1,3 1,4 @@
option('jdk_home', type : 'string', description : 'The path to the jdk install folder')
+option('wofij_path', type : 'string', description : 'The path to the wofij jar')
option('mode_class', type : 'string', description : 'The class that implements mode')
-option('class_path', type : 'string', description : 'The class path to use, defaults to the path of the DSO determined at runtime, primarily used for debugging')
No newline at end of file
+option('mode_path', type : 'string', description : 'The path to your mode\'s module')
A => src/module-info.java +3 -0
@@ 0,0 1,3 @@
+module ninja.scoopta.software.wofij {
+ exports ninja.scoopta.software.wofij;
+}
No newline at end of file
M src/ninja/scoopta/software/wofij/Wofi.java +18 -3
@@ 1,5 1,5 @@
/*
- * Copyright (C) 2020 Scoopta
+ * Copyright (C) 2020-2023 Scoopta
* This file is part of WofiJ
* WofiJ is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ 17,6 17,10 @@
package ninja.scoopta.software.wofij;
+import java.util.Set;
+import java.nio.file.*;
+import java.lang.module.*;
+
public final class Wofi {
final long mode;
private static Wofi wofi;
@@ 35,9 39,20 @@ public final class Wofi {
}
}
- private static final void load(long mode, Class<?> clazz) {
+ private static final void load(long mode, byte[] clazz, byte[] path) {
try {
- impl = (Mode) clazz.getConstructor().newInstance();
+ String[] p = new String(path).split(":");
+ Path[] paths = new Path[p.length];
+ for(int count = 0; count < p.length; ++count) {
+ paths[count] = Paths.get(p[count]);
+ }
+ String[] split = new String(clazz).split("/");
+
+ ModuleLayer boot = ModuleLayer.boot();
+ Configuration config = boot.configuration().resolve(ModuleFinder.of(paths), ModuleFinder.of(), Set.of(split[0]));
+ ModuleLayer layer = boot.defineModulesWithOneLoader(config, ClassLoader.getSystemClassLoader());
+ Module module = layer.findModule(split[0]).get();
+ impl = (Mode) Class.forName(module, split[1]).getConstructor().newInstance();
wofi = new Wofi(mode);
impl.load(wofi);
} catch(Exception e) {
M wofi_jni/src/wofi_jni.c +17 -16
@@ 1,5 1,5 @@
/*
- * Copyright (C) 2020-2022 Scoopta
+ * Copyright (C) 2020-2023 Scoopta
* This file is part of WofiJ
* WofiJ is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ 155,15 155,12 @@ void init(struct mode* _mode, struct map
void load(struct mode* _mode) {
mode = _mode;
JavaVMInitArgs args;
- JavaVMOption options[1];
-#ifdef CLASS_PATH
- char* cp = CLASS_PATH;
-#else
- char* cp = wofi_get_dso_path(mode);
-#endif
- options[0].optionString = utils_concat(2, "-Djava.class.path=", cp);
+ JavaVMOption options[2];
+ char* p = MODULE_PATH;
+ options[0].optionString = "-Djdk.module.main=ninja.scoopta.software.wofij";
+ options[1].optionString = utils_concat(2, "--module-path=", p);
args.version = JNI_VERSION_10;
- args.nOptions = 1;
+ args.nOptions = 2;
args.options = options;
args.ignoreUnrecognized = false;
@@ 226,13 223,17 @@ void load(struct mode* _mode) {
wofi = (*env)->NewGlobalRef(env, class);
(*env)->RegisterNatives(env, wofi, natives, sizeof(natives) / sizeof(JNINativeMethod));
- jmethodID method = (*env)->GetStaticMethodID(env, wofi, "load", "(JLjava/lang/Class;)V");
- jclass mode_class = (*env)->FindClass(env, MODE_CLASS);
- if(mode_class == NULL) {
- fprintf(stderr, "Cannot find main class\n");
- exit(1);
- }
- (*env)->CallStaticVoidMethod(env, wofi, method, mode, mode_class);
+ jmethodID method = (*env)->GetStaticMethodID(env, wofi, "load", "(J[B[B)V");
+
+ size_t mode_class_l = strlen(MODE_CLASS);
+ jbyteArray arr = (*env)->NewByteArray(env, mode_class_l);
+ (*env)->SetByteArrayRegion(env, arr, 0, mode_class_l, (jbyte*) MODE_CLASS);
+
+ size_t mode_path_l = strlen(MODE_PATH);
+ jbyteArray arr2 = (*env)->NewByteArray(env, mode_path_l);
+ (*env)->SetByteArrayRegion(env, arr2, 0, mode_path_l, (jbyte*) MODE_PATH);
+
+ (*env)->CallStaticVoidMethod(env, wofi, method, mode, arr, arr2);
map_jni_init(env);
cache_jni_init(env);