Add exports for dynamic layers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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