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