Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Add exports for dynamic layers
/*
* For modules on the boot-layer one can add exports using --add-exports but it looks like there's no
* public API to do the same when constructing a custom layer
*/
package javamodules;
import java.lang.ModuleLayer.Controller;
import java.lang.module.Configuration;
import java.lang.module.ModuleFinder;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class FeatureRichLayerCreation {
private static Path JAVAFX_MODULES = Paths.get("/Users/tomschindl/Downloads/javafx-sdk-11/lib");
@SuppressWarnings("deprecation")
public static void main(String[] args) throws Throwable {
System.err.println("VERSION: " + System.getProperty("java.version"));
Path[] array = Files.list(JAVAFX_MODULES) //
.filter(p -> {
String name = p.getFileName().toString();
return name.startsWith("javafx.") && name.endsWith(".jar");
}) //
.toArray(i -> new Path[i]);
Set<String> modules = Stream.of(array) //
.map(Path::getFileName) //
.map(Path::toString) //
.map(n -> n.substring(0, n.length() - ".jar".length())) //
.collect(Collectors.toSet());
URL[] urls = Stream.of(array).map( Path::toFile).map( f -> {
try {
return f.toURL();
} catch(Throwable t) {
return null;
}
} ).toArray( i -> new URL[i]);
URLClassLoader c = new URLClassLoader(urls, FeatureRichLayerCreation.class.getClassLoader()) {
protected java.lang.Class<?> findClass(String moduleName, String name) {
try {
return findClass(name);
} catch (ClassNotFoundException e) {}
return null;
}
protected URL findResource(String moduleName, String name) throws java.io.IOException {
return findResource(name);
}
};
ModuleFinder fxModuleFinder = ModuleFinder.of(array);
ModuleFinder empty = ModuleFinder.of(new Path[0]);
ModuleLayer bootLayer = ModuleLayer.boot();
Configuration configuration = bootLayer.configuration();
Configuration newConfiguration = configuration.resolve(fxModuleFinder, empty, modules);
Controller moduleLayerController = ModuleLayer.defineModules(newConfiguration, Arrays.asList(bootLayer), s -> c);
ModuleLayer moduleLayer = moduleLayerController.layer();
moduleLayerController.addExports(moduleLayer.findModule("javafx.base").get(), "com.sun.javafx.runtime", FeatureRichLayerCreation.class.getModule());
ClassLoader loader = moduleLayer.findLoader("javafx.base");
System.err.println(loader.loadClass("javafx.beans.property.SimpleStringProperty").newInstance());
System.err.println(loader.loadClass("com.sun.javafx.runtime.VersionInfo").newInstance());
Class<?> loadClass = loader.loadClass("com.sun.glass.utils.NativeLibLoader");
System.err.println(loadClass.getModule());
// we need to overwrite findResource(String,String)
System.err.println(loadClass.getResource("NativeLibLoader.class"));
// we need to overwrite findClass(String,String)
System.err.println(Class.forName(moduleLayer.findModule("javafx.base").get(), "javafx.beans.property.SimpleIntegerProperty"));
c.close();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.