Примечание : У меня очень мало опыта работы с системой Module, представленной в Java 9.
У меня есть Java-процесс, который должен запустить другой файл Jar, загрузив и выполнив его с помощью отражения.Обратите внимание, что оба Jar-файла зависят от среды JavaFX, которая была отсоединена от JDK в Версии 11 и в результате может быть загружена во второй раз.
Здесь Исходная версия, которая работала на JDK версии 8:
val ideFile = File(binFolder, "Sk-IDE.jar")
val classLoader = ClassLoader.getSystemClassLoader() as URLClassLoader
val method = URLClassLoader::class.java.getDeclaredMethod("addURL", URL::class.java)
method.isAccessible = true
method.invoke(classLoader, ideFile.toURI().toURL())
val coreManager = Class.forName("com.skide.CoreManager")
val instance = coreManager.newInstance()
coreManager.getDeclaredMethod("bootstrap", Array<String>::class.java).invoke(instance, State.args)
(Рефлексивный вызов addURL был необходим, потому что в противном случае загрузчик Jar не смог бы загрузить свои fxml-файлы)
Этот подход вызывает это исключение в JDK 11:
java.lang.ClassCastException: class jdk.internal.loader.ClassLoaders$AppClassLoader cannot be cast to class java.net.URLClassLoader (jdk.internal.loader.ClassLoaders$AppClassLoader and java.net.URLClassLoader are in module java.base of loader 'bootstrap')
Подход к созданию нового URLClassLoader
:
val child = URLClassLoader(arrayOf(URL(ideFile.toURI().toURL().toString())), Installer::class.java.classLoader)
val coreManager = Class.forName("com.skide.CoreManager", true, child)
val instance = coreManager.newInstance()
Platform.runLater {
coreManager.getDeclaredMethod("bootstrap", Array<String>::class.java).invoke(instance, State.args)
}
Создает исключение, связанное с JavaFX:
Exception in thread "JavaFX Application Thread" [20.11.2018 20:13:41 | ERROR] java.security.PrivilegedActionException: java.lang.reflect.InvocationTargetException
[20.11.2018 20:13:41 | ERROR] at java.base/java.security.AccessController.doPrivileged(Native Method)
[20.11.2018 20:13:41 | ERROR] at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
[20.11.2018 20:13:41 | ERROR] at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
[20.11.2018 20:13:41 | ERROR] at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
[20.11.2018 20:13:41 | ERROR] at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
[20.11.2018 20:13:41 | ERROR] at java.base/java.lang.Thread.run(Thread.java:834)
[20.11.2018 20:13:41 | ERROR] Caused by: java.lang.reflect.InvocationTargetException
[20.11.2018 20:13:41 | ERROR] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[20.11.2018 20:13:41 | ERROR] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[20.11.2018 20:13:41 | ERROR] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[20.11.2018 20:13:41 | ERROR] at java.base/java.lang.reflect.Method.invoke(Method.java:566)
[20.11.2018 20:13:41 | ERROR] at com.skide.installer.Installer$start$2$1$1.run(Installer.kt:249)
[20.11.2018 20:13:41 | ERROR] at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
[20.11.2018 20:13:41 | ERROR] ... 6 more
[20.11.2018 20:13:41 | ERROR] Caused by: javafx.fxml.LoadException:
unknown path:9
[20.11.2018 20:13:41 | ERROR] at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2625)
[20.11.2018 20:13:41 | ERROR] at javafx.fxml.FXMLLoader.access$700(FXMLLoader.java:105)
[20.11.2018 20:13:41 | ERROR] at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:930)
[20.11.2018 20:13:41 | ERROR] at javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(FXMLLoader.java:980)
[20.11.2018 20:13:41 | ERROR] at javafx.fxml.FXMLLoader$Element.processStartElement(FXMLLoader.java:227)
[20.11.2018 20:13:41 | ERROR] at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:752)
[20.11.2018 20:13:41 | ERROR] at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2722)
[20.11.2018 20:13:41 | ERROR] at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2552)
[20.11.2018 20:13:41 | ERROR] at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2450)
[20.11.2018 20:13:41 | ERROR] at com.skide.CoreManager$bootstrap$1.invoke(CoreManager.kt:47)
[20.11.2018 20:13:41 | ERROR] at com.skide.CoreManager$bootstrap$1.invoke(CoreManager.kt:24)
[20.11.2018 20:13:41 | ERROR] at com.skide.CoreManager.bootstrap(CoreManager.kt:136)
[20.11.2018 20:13:41 | ERROR] ... 12 more
[20.11.2018 20:13:41 | ERROR] Caused by: java.lang.ClassNotFoundException: com.skide.gui.controllers.SplashGuiController
[20.11.2018 20:13:41 | ERROR] at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
[20.11.2018 20:13:41 | ERROR] at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
[20.11.2018 20:13:41 | ERROR] at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
[20.11.2018 20:13:41 | ERROR] at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:928)
[20.11.2018 20:13:41 | ERROR] ... 21 more
Каков наилучший способ решить эту проблему?
С уважением, Liz3
EDIT
С помощью xtratic решение было на самом деле простым:
Я просто добавил child
URLClassloader кCoreManager # загрузочный рефлексивный вызов, метод начальной загрузки CoreManager (загруженный файл jar), который передает этот URLClassloader всем загрузчикам FXML.