diff --git a/modules/core/org.eclipse.fx.osgi/src/main/java/org/eclipse/fx/osgi/fxloader/FXClassLoader.java b/modules/core/org.eclipse.fx.osgi/src/main/java/org/eclipse/fx/osgi/fxloader/FXClassLoader.java index 7aac58f4c..4f385bf06 100644 --- a/modules/core/org.eclipse.fx.osgi/src/main/java/org/eclipse/fx/osgi/fxloader/FXClassLoader.java +++ b/modules/core/org.eclipse.fx.osgi/src/main/java/org/eclipse/fx/osgi/fxloader/FXClassLoader.java @@ -106,7 +106,7 @@ private static boolean isEqualGreaterJDK11() { @SuppressWarnings("resource") @Override - public Class postFindClass(String name, ModuleClassLoader moduleClassLoader) throws ClassNotFoundException { + public synchronized Class postFindClass(String name, ModuleClassLoader moduleClassLoader) throws ClassNotFoundException { if( this.reentrance ) { if (FXClassloaderConfigurator.DEBUG) { System.err.println("FXClassLoader#postFindClass - Loop detected returning null"); @@ -185,13 +185,13 @@ private Class findClassJavaFX11(String name, ModuleClassLoader moduleClassLoa System.err.println("FXClassLoader#findClassJavaFX11 - started" ); //$NON-NLS-1$ System.err.println("FXClassLoader#findClassJavaFX11 - Loading class '" + name + "' for " + moduleClassLoader); //$NON-NLS-1$//$NON-NLS-2$ } - + synchronized (this) { if( this.j11ModulePackages != null && this.j11ModulePackages.isEmpty() ) { if (FXClassloaderConfigurator.DEBUG) { System.err.println("FXClassLoader#findClassJavaFX11 - Loader is empty. Returning null." ); //$NON-NLS-1$ } - + return null; } if( this.boostrappingModules.get() ) { @@ -209,7 +209,7 @@ private Class findClassJavaFX11(String name, ModuleClassLoader moduleClassLoa if( ! modules.isEmpty() ) { this.j11Classloader = layer.findLoader(modules.iterator().next().getName()); this.j11ModulePackages = modules.stream().flatMap( m -> m.getPackages().stream()).collect(Collectors.toSet()); - + if( getSWTClassloader(this.frameworkContext) != null ) { if (FXClassloaderConfigurator.DEBUG) { System.err.println("FXClassLoader#findClassJavaFX11 - We run inside SWT don't let the platform quit automatically" ); //$NON-NLS-1$ @@ -242,12 +242,12 @@ private Class findClassJavaFX11(String name, ModuleClassLoader moduleClassLoa } else if( ! this.j11ModulePackages.contains(name.substring(0,lastIndexOf)) ) { return null; } - + return loadedClass = this.j11Classloader.loadClass(name); } finally { if (FXClassloaderConfigurator.DEBUG) { System.err.println("FXClassLoader#findClassJavaFX11 - "+loadedClass+" - ended"); //$NON-NLS-1$ - } + } } } @@ -280,18 +280,18 @@ private synchronized ModuleLayerWrapper getModuleLayer() throws Throwable { } } } - + ClassLoader parentClassloader = getSWTClassloader(this.frameworkContext); if (parentClassloader == null) { parentClassloader = getClass().getClassLoader(); } - + if( FXClassloaderConfigurator.DEBUG ) { System.err.println("FXClassLoader#getModuleLayer - Parent Classloader: " + parentClassloader); } this.moduleLayer = initModuleLayer(parentClassloader, providers, collectModifications(this.frameworkContext)); - + if( FXClassloaderConfigurator.DEBUG ) { System.err.println("FXClassLoader#getModuleLayer - Module created: " + moduleLayer); } @@ -312,10 +312,10 @@ private synchronized ModuleLayerWrapper getModuleLayer() throws Throwable { return this.moduleLayer; } - + private static String replaceProperties(String path) { Properties properties = System.getProperties(); - + String rv = path; for( Entry e : properties.entrySet() ) { String value = e.getValue() + ""; //$NON-NLS-1$ @@ -324,18 +324,18 @@ private static String replaceProperties(String path) { } else { value = value.replace("file:", ""); //$NON-NLS-1$ //$NON-NLS-2$ } - + rv = rv.replace("$("+e.getKey()+")", value); //$NON-NLS-1$//$NON-NLS-2$ } - + return rv; } - + private static JavaModuleLayerModification collectModifications(BundleContext context) { Set reads = new HashSet<>(); Set opens = new HashSet<>(); Set exports = new HashSet<>(); - + Bundle[] bundles = context.getBundles(); for (Bundle b : bundles) { if( FXClassloaderConfigurator.DEBUG ) { @@ -364,44 +364,44 @@ private static JavaModuleLayerModification collectModifications(BundleContext co } } else { if( FXClassloaderConfigurator.DEBUG ) { - System.err.println("Skipped Bundle: " + b); + System.err.println("Skipped Bundle: " + b); } } } - + String addReads = System.getProperty("efxclipse.osgi.hook.add-reads"); //$NON-NLS-1$ String addOpens = System.getProperty("efxclipse.osgi.hook.add-opens"); //$NON-NLS-1$ String addExports = System.getProperty("efxclipse.osgi.hook.add-exports"); //$NON-NLS-1$ - + if( addReads != null ) { reads.addAll(toReads(addReads, null)); } - + if( addExports != null ) { exports.addAll(toOpenExports(addExports, null)); } - + if( addOpens != null ) { opens.addAll(toOpenExports(addOpens, null)); } - + if( FXClassloaderConfigurator.DEBUG ) { System.err.println("FXClassLoader#collectModifications - Reads: " + reads); System.err.println("FXClassLoader#collectModifications - Exports: " + exports); System.err.println("FXClassLoader#collectModifications - Opens: " + opens); } - - + + return new JavaModuleLayerModification(context.getBundles(),reads, exports, opens); } - + private static String adaptAllUnnamed(String value, Bundle bundle) { if( value.endsWith("=.") && bundle != null ) { //$NON-NLS-1$ return value.replace("=.", "=BUNDLE(@"+bundle.getBundleId()+")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } return value; } - + private static Set toReads(String value, Bundle bundle) { return Stream.of(value.split(",")) //$NON-NLS-1$ .map( v -> adaptAllUnnamed(v, bundle)) @@ -419,7 +419,7 @@ private static Set toOpenExports(String value, Bundle bundle) { .map(Optional::get) // .collect(Collectors.toSet()); } - + private static ModuleLayerWrapper initModuleLayer(ClassLoader parentClassloader, List bundles, JavaModuleLayerModification modifications) throws Throwable { try { if( Boolean.getBoolean("efxclipse.osgi.hook.advanced-modules") || ! modifications.isEmpty() ) { //$NON-NLS-1$ @@ -432,47 +432,47 @@ private static ModuleLayerWrapper initModuleLayer(ClassLoader parentClassloader, throw t; } } - + private static ModuleLayerWrapper advancedModuleLayerBoostrap(ClassLoader parentClassloader, List bundles, JavaModuleLayerModification modifications) throws Throwable { if( FXClassloaderConfigurator.DEBUG ) { System.err.println("FXClassLoader#advancedModuleLayerBoostrap - Using advanced layer creation to apply patches"); //$NON-NLS-1$ } - + Path[] paths = bundles.stream().map(p -> p.path).toArray(i -> new Path[i]); Set modules = bundles.stream().map(p -> p.module).collect(Collectors.toSet()); - + @SuppressWarnings("deprecation") URL[] urls = Stream.of(paths).map( Path::toFile).map( f -> { try { return f.toURL(); } catch(Throwable t) { - return null; + return null; } } ).toArray( i -> new URL[i]); - + if( FXClassloaderConfigurator.DEBUG ) { for( FXProviderBundle b : bundles ) { System.err.println( "FXClassLoader#advancedModuleLayerBoostrap - " + b.module + " => " + b.path); //$NON-NLS-1$ //$NON-NLS-2$ } } - + URLClassLoader c = new URLClassLoader(urls, parentClassloader) { // Method is defined on Java-9 onwards @SuppressWarnings("unused") protected java.lang.Class findClass(String moduleName, String name) { try { - return findClass(name); + return findClass(name); } catch (ClassNotFoundException e) { /* intentional empty */} return null; } - + // Method is defined on Java-9 onwards @SuppressWarnings("unused") protected URL findResource(String moduleName, String name) throws IOException { return findResource(name); } }; - + ModuleFinderWrapper fxModuleFinder = ModuleFinderWrapper.of(paths); ModuleFinderWrapper empty = ModuleFinderWrapper.of(); ModuleLayerWrapper bootLayer = ModuleLayerWrapper.boot(); @@ -481,14 +481,14 @@ protected URL findResource(String moduleName, String name) throws IOException { Function clComputer = s -> c; ControllerWrapper moduleLayerController = ModuleLayerWrapper.defineModules(newConfiguration, Arrays.asList(bootLayer), clComputer); modifications.applyConfigurations(moduleLayerController); - + return moduleLayerController.layer(); } - + private static ModuleLayerWrapper defaultModuleLayerBootstrap(ClassLoader parentClassloader, List bundles) throws Throwable { Path[] paths = bundles.stream().map(p -> p.path).toArray(i -> new Path[i]); Set modules = bundles.stream().map(p -> p.module).collect(Collectors.toSet()); - + if( FXClassloaderConfigurator.DEBUG ) { for( FXProviderBundle b : bundles ) { System.err.println( "FXClassLoader#defaultModuleLayerBootstrap - " + b.module + " => " + b.path); //$NON-NLS-1$ //$NON-NLS-2$ @@ -501,7 +501,7 @@ private static ModuleLayerWrapper defaultModuleLayerBootstrap(ClassLoader parent ModuleFinderWrapper of = ModuleFinderWrapper.of(); ConfigurationWrapper cf = configuration.resolve(finder, of, modules); ModuleLayerWrapper layer = boot.defineModulesWithOneLoader(cf, parentClassloader); - + return layer; } @@ -600,7 +600,7 @@ private static ClassLoader getSWTClassloader(BundleContext context) { private static List getDeployedJavaModuleBundlePaths(BundleContext context) { List paths = new ArrayList<>(); - + if( FXClassloaderConfigurator.DEBUG ) { System.err.println("FXClassLoader#getDeployedJavaModuleBundlePaths - Loading libraries from deployed modules"); //$NON-NLS-1$ } @@ -617,7 +617,7 @@ private static List getDeployedJavaModuleBundlePaths(BundleCon if (entry == null) { entry = b.getEntry(name.replace('.', '-') + ".jar"); //$NON-NLS-1$ } - + if( FXClassloaderConfigurator.DEBUG ) { System.err.println("FXClassLoader#getDeployedJavaModuleBundlePaths - Found Jar '"+entry+"'"); //$NON-NLS-1$//$NON-NLS-2$ } @@ -628,7 +628,7 @@ private static List getDeployedJavaModuleBundlePaths(BundleCon URL url = converter.toFileURL(entry); if( FXClassloaderConfigurator.DEBUG ) { System.err.println("FXClassLoader#getDeployedJavaModuleBundlePaths - Converted URL: " + url); //$NON-NLS-1$ - } + } String file = url.getFile(); if( System.getProperty("os.name").toLowerCase().contains("windows") ) { //$NON-NLS-1$ //$NON-NLS-2$ if( file.startsWith("/") ) { //$NON-NLS-1$ @@ -646,7 +646,7 @@ private static List getDeployedJavaModuleBundlePaths(BundleCon } } } - + return paths; } @@ -829,21 +829,21 @@ protected Class findClass(String name) throws ClassNotFoundException { if (name.startsWith("javafx.embed.swt")) { //$NON-NLS-1$ if (this.checkFlag == null) { this.checkFlag = Boolean.TRUE; - + // On JDK-8 we need to check for GTK3 if( isJDK8() ) { boolean supportsGtk3 = false; String version = System.getProperty("java.version", ""); //$NON-NLS-1$//$NON-NLS-2$ - + Matcher matcher = Pattern.compile(".+_(\\d+).*").matcher(version); //$NON-NLS-1$ if( matcher.matches() && matcher.groupCount() > 0 ) { supportsGtk3 = Integer.parseInt(matcher.group(1)) >= 202; } - + if( ! supportsGtk3 ) { Boolean isGTK3 = Boolean.FALSE; try { - + if (FXClassloaderConfigurator.DEBUG) { System.err.println( "FXModuleClassloader#findLocalClass - Someone is trying to load FXCanvas. Need to check for GTK3"); //$NON-NLS-1$ @@ -857,7 +857,7 @@ protected Class findClass(String name) throws ClassNotFoundException { System.err.println( "FXModuleClassloader#findLocalClass - We are on GTK need to take a closer look"); //$NON-NLS-1$ } - + // Constants moved with Photon try { isGTK3 = (Boolean) loadClass("org.eclipse.swt.internal.gtk.GTK").getDeclaredField("GTK3") //$NON-NLS-1$//$NON-NLS-2$ @@ -888,11 +888,11 @@ protected Class findClass(String name) throws ClassNotFoundException { "FXModuleClassloader#findLocalClass - We are on GTK3 - too bad need to disable JavaFX for now else we'll crash the JVM"); //$NON-NLS-1$ } throw new ClassNotFoundException("SWT is running with GTK3 but JavaFX is linked against GTK2"); //$NON-NLS-1$ - } + } } } - + try { loadClass("javafx.application.Platform").getDeclaredMethod("setImplicitExit", boolean.class) //$NON-NLS-1$ //$NON-NLS-2$ .invoke(null, Boolean.FALSE);