/* * This is free and unencumbered software released into the public domain. * * Anyone is free to copy, modify, publish, use, compile, sell, or * distribute this software, either in source code form or as a compiled * binary, for any purpose, commercial or non-commercial, and by any * means. * * In jurisdictions that recognize copyright laws, the author or authors * of this software dedicate any and all copyright interest in the * software to the public domain. We make this dedication for the benefit * of the public at large and to the detriment of our heirs and * successors. We intend this dedication to be an overt act of * relinquishment in perpetuity of all present and future rights to this * software under copyright law. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * For more information, please refer to <http://unlicense.org/> */ package javafx.embed.swt; import java.io.File; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.net.URLClassLoaderExt; import java.nio.file.Paths; import java.security.ProtectionDomain; import org.eclipse.osgi.internal.framework.EquinoxConfiguration; import org.eclipse.osgi.internal.loader.ModuleClassLoader; import org.eclipse.osgi.internal.loader.classpath.ClasspathEntry; import org.eclipse.osgi.internal.loader.classpath.ClasspathManager; import org.eclipse.osgi.storage.BundleInfo.Generation; import org.eclipse.osgi.storage.bundlefile.BundleFile; import org.eclipse.osgi.storage.bundlefile.ZipBundleFile; /** * SWT-JavaFX載入器 * * @author AqD */ @SuppressWarnings("restriction") public final class FXLoader { /** * 載入JavaFX整合用的<b>jfxswt.jar</b> * <ul> * <li>掛載<b>jfxswt.jar</b>到目前的{@link ClassLoader}內</li> * </ul> */ public static void load() { classLoader_addClasspath( FXLoader.class.getClassLoader(), Paths.get(System.getProperty("java.home"), "lib", "jfxswt.jar").toFile()); } /** * 於{@link ClassLoader}加上新的搜尋路徑 * <p> * 支援以下格式的{@link ClassLoader}: * <ul> * <li>{@link java.net.URLClassLoader}:系統的類別載入器</li> * <li>{@link org.eclipse.osgi.internal.loader.ModuleClassLoader}:Eclipse外掛的類別載入器</li> * </ul> * </p> * * @param classLoader 類別載入器 * @param jarFile 要加入類別搜尋路徑的JAR檔位置 * @throws UnsupportedOperationException 不支援的{@code classLoader}型態 */ private static void classLoader_addClasspath(ClassLoader classLoader, File jarFile) { /* * Java預設 */ if (classLoader instanceof URLClassLoader) { URL jarURL; try { jarURL = jarFile.toURI().toURL(); } catch (MalformedURLException e) { throw new RuntimeException(e); } URLClassLoaderExt.addURL((URLClassLoader) classLoader, jarURL); } /* * Eclipse 4.3 Kepler */ /* else if (classLoader instanceof DefaultClassLoader) { try { DefaultClassLoader defaultClassLoader = (DefaultClassLoader) classLoader; ClasspathManager classpathManager = defaultClassLoader.getClasspathManager(); // Get ClasspathManager.entries if (ClasspathManager_entriesField == null) { ClasspathManager_entriesField = ClasspathManager.class.getDeclaredField("entries"); ClasspathManager_entriesField.setAccessible(true); Field_modifiersField.setInt(ClasspathManager_entriesField, ClasspathManager_entriesField.getModifiers() & ~Modifier.FINAL); } ClasspathEntry[] oldEntries = (ClasspathEntry[]) ClasspathManager_entriesField.get(classpathManager); // Create ClasspathEntry for the given jarFile BundleFile jarBundleFile = new ZipBundleFile(jarFile, null); ProtectionDomain domain = oldEntries[0].getDomain(); ClasspathEntry jarEntry = new ClasspathEntry(jarBundleFile, domain); // Prepare new entries ClasspathEntry[] newEntries = new ClasspathEntry[oldEntries.length + 1]; System.arraycopy(oldEntries, 0, newEntries, 0, oldEntries.length); newEntries[oldEntries.length] = jarEntry; // Set new entries to replace the old one ClasspathManager_entriesField.set(classpathManager, newEntries); E3Log.logger().fine("added classpath: " + jarFile); } catch (IOException | ReflectiveOperationException e) { throw new RuntimeException(e); } } */ /* * Eclipse 4.4 Luna */ else if (classLoader instanceof ModuleClassLoader) { try { ModuleClassLoader moduleClassLoader = (ModuleClassLoader) classLoader; ClasspathManager classpathManager = moduleClassLoader.getClasspathManager(); // if (Field_modifiersField == null) { Field_modifiersField = Field.class.getDeclaredField("modifiers"); Field_modifiersField.setAccessible(true); } // Get Configuration if (ModuleClassLoader_getConfigurationMethod == null) { ModuleClassLoader_getConfigurationMethod = ModuleClassLoader.class .getDeclaredMethod("getConfiguration"); ModuleClassLoader_getConfigurationMethod.setAccessible(true); } EquinoxConfiguration config = (EquinoxConfiguration) ModuleClassLoader_getConfigurationMethod .invoke(moduleClassLoader); // Get ClasspathManager.entries if (ClasspathManager_entriesField == null) { ClasspathManager_entriesField = ClasspathManager.class.getDeclaredField("entries"); ClasspathManager_entriesField.setAccessible(true); Field_modifiersField.setInt(ClasspathManager_entriesField, ClasspathManager_entriesField.getModifiers() & ~Modifier.FINAL); } ClasspathEntry[] oldEntries = (ClasspathEntry[]) ClasspathManager_entriesField .get(classpathManager); // Create ClasspathEntry for the given jarFile BundleFile jarBundleFile = new ZipBundleFile(jarFile, null, null, config.getDebug()); ProtectionDomain domain = oldEntries[0].getDomain(); Generation generation = classpathManager.getGeneration(); ClasspathEntry jarEntry = new ClasspathEntry(jarBundleFile, domain, generation); // Prepare new entries ClasspathEntry[] newEntries = new ClasspathEntry[oldEntries.length + 1]; System.arraycopy(oldEntries, 0, newEntries, 0, oldEntries.length); newEntries[oldEntries.length] = jarEntry; // Set new entries to replace the old one ClasspathManager_entriesField.set(classpathManager, newEntries); } catch (IOException | ReflectiveOperationException e) { throw new RuntimeException(e); } } else { throw new UnsupportedOperationException(classLoader.toString()); } } private static Field Field_modifiersField; private static Method ModuleClassLoader_getConfigurationMethod; private static Field ClasspathManager_entriesField; private FXLoader() { } }