From d19f39e840103d5827b918ce28cac9091f286b3f Mon Sep 17 00:00:00 2001 From: Mario Ivankovits Date: Wed, 22 Feb 2017 21:20:24 +0100 Subject: [PATCH] alternatively to creating a classloader for the application at runtime, allow to configure at fxlauncher classloader at boot-time and add the new classpath-entries to this classloader. this should avoid problems where the jdk itself does use Class.forName and might not find application-classes due to using the wrong classloader. --- .../fxlauncher/FxlauncherClassCloader.java | 68 +++++++++++++++++++ src/main/java/fxlauncher/Launcher.java | 23 +++++-- 2 files changed, 85 insertions(+), 6 deletions(-) create mode 100644 src/main/java/fxlauncher/FxlauncherClassCloader.java diff --git a/src/main/java/fxlauncher/FxlauncherClassCloader.java b/src/main/java/fxlauncher/FxlauncherClassCloader.java new file mode 100644 index 0000000..fcae265 --- /dev/null +++ b/src/main/java/fxlauncher/FxlauncherClassCloader.java @@ -0,0 +1,68 @@ +package fxlauncher; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by im on 22.02.17. + */ +public class FxlauncherClassCloader extends URLClassLoader +{ + public FxlauncherClassCloader(ClassLoader parentClassLoader) + { + super(buildClasspath(System.getProperty("java.class.path")), parentClassLoader); + } + + void addUrls(List urls) + { + for (URL url : urls) + { + this.addURL(url); + } + } + + private static URL[] buildClasspath(String classPath) + { + if (classPath == null || classPath.trim().length() < 1) + { + return new URL[0]; + } + + List urls = new ArrayList<>(); + + int pos; + while ((pos = classPath.indexOf(File.pathSeparatorChar)) > -1) + { + String part = classPath.substring(0, pos); + + addClasspathPart(urls, part); + + classPath = classPath.substring(pos + 1); + } + + addClasspathPart(urls, classPath); + + return urls.toArray(new URL[urls.size()]); + } + + private static void addClasspathPart(List urls, String part) + { + if (part == null || part.trim().length() < 1) + { + return; + } + + try + { + urls.add(new File(part).toURI().toURL()); + } + catch (MalformedURLException e) + { + throw new RuntimeException(e); + } + } +} diff --git a/src/main/java/fxlauncher/Launcher.java b/src/main/java/fxlauncher/Launcher.java index 1c491de..d0b3699 100644 --- a/src/main/java/fxlauncher/Launcher.java +++ b/src/main/java/fxlauncher/Launcher.java @@ -153,10 +153,24 @@ private void createUpdateWrapper() { }); } - private URLClassLoader createClassLoader(Path cacheDir) { + private ClassLoader createClassLoader(Path cacheDir) { List libs = manifest.files.stream().filter(LibraryFile::loadForCurrentPlatform).map(it -> it.toURL(cacheDir)).collect(Collectors.toList()); - return new URLClassLoader(libs.toArray(new URL[libs.size()])); + ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); + if (systemClassLoader instanceof FxlauncherClassCloader) + { + ((FxlauncherClassCloader) systemClassLoader).addUrls(libs); + return systemClassLoader; + } + else + { + ClassLoader classLoader = new URLClassLoader(libs.toArray(new URL[libs.size()])); + FXMLLoader.setDefaultClassLoader(classLoader); + Thread.currentThread().setContextClassLoader(classLoader); + Platform.runLater(() -> Thread.currentThread().setContextClassLoader(classLoader)); + + return classLoader; + } } private void launchAppFromManifest(boolean showWhatsnew) throws Exception { @@ -247,10 +261,7 @@ private void createApplication() throws Exception { Path cacheDir = manifest.resolveCacheDir(getParameters() != null ? getParameters().getNamed() : null); - URLClassLoader classLoader = createClassLoader(cacheDir); - FXMLLoader.setDefaultClassLoader(classLoader); - Thread.currentThread().setContextClassLoader(classLoader); - Platform.runLater(() -> Thread.currentThread().setContextClassLoader(classLoader)); + ClassLoader classLoader = createClassLoader(cacheDir); Class appclass = (Class) classLoader.loadClass(manifest.launchClass); PlatformImpl.runAndWait(() ->