1 /******************************************************************************* 2 * Copyright (c) 2007, 2017 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 *******************************************************************************/ 14 package org.eclipse.equinox.p2.tests.embeddedequinox; 15 16 import java.io.IOException; 17 import java.lang.reflect.Method; 18 import java.net.URL; 19 import java.net.URLClassLoader; 20 import java.util.Enumeration; 21 import java.util.Map; 22 import org.osgi.framework.BundleContext; 23 24 /* 25 * This class assumes the bundle's classloader only has access to org.osgi.framework 26 * from the hosting framework. Any more access could result in ClassVerifier errors. 27 */ 28 public class EmbeddedEquinox { 29 private final Map<String, String> frameworkProperties; 30 private final String[] frameworkArgs; 31 private Class<?> eclipseStarterClazz; 32 private BundleContext context; 33 private URL[] frameworkClassPath; 34 EmbeddedEquinox(Map<String, String> frameworkProperties, String[] frameworkArgs, URL[] frameworkClassPath)35 public EmbeddedEquinox(Map<String, String> frameworkProperties, String[] frameworkArgs, URL[] frameworkClassPath) { 36 this.frameworkProperties = frameworkProperties; 37 this.frameworkArgs = frameworkArgs; 38 this.frameworkClassPath = frameworkClassPath; 39 } 40 startFramework()41 public BundleContext startFramework() { 42 System.setProperty("osgi.framework.useSystemProperties", "false"); 43 try { 44 @SuppressWarnings("resource") 45 // For some reason when you close the framework loader, tests fail! 46 URLClassLoader frameworkLoader = new FrameworkClassLoader(frameworkClassPath, this.getClass().getClassLoader()); 47 eclipseStarterClazz = frameworkLoader.loadClass("org.eclipse.core.runtime.adaptor.EclipseStarter"); 48 49 Method setInitialProperties = eclipseStarterClazz.getMethod("setInitialProperties", Map.class); //$NON-NLS-1$ 50 setInitialProperties.invoke(null, frameworkProperties); 51 52 Method runMethod = eclipseStarterClazz.getMethod("startup", String[].class, Runnable.class); //$NON-NLS-1$ 53 context = (BundleContext) runMethod.invoke(null, frameworkArgs, null); 54 } catch (Throwable t) { 55 if (t instanceof RuntimeException) 56 throw (RuntimeException) t; 57 throw new RuntimeException(t); 58 } 59 return context; 60 } 61 shutdown()62 public void shutdown() { 63 try { 64 Method shutdownMethod = eclipseStarterClazz.getMethod("shutdown"); //$NON-NLS-1$ 65 shutdownMethod.invoke((Object[]) null); 66 67 } catch (Throwable t) { 68 if (t instanceof RuntimeException) 69 throw (RuntimeException) t; 70 throw new RuntimeException(t); 71 } 72 } 73 74 public class FrameworkClassLoader extends URLClassLoader { 75 ClassLoader embeddedBundleLoader; 76 FrameworkClassLoader(URL[] urls, ClassLoader parent)77 public FrameworkClassLoader(URL[] urls, ClassLoader parent) { 78 super(urls, null); 79 this.embeddedBundleLoader = parent; 80 } 81 82 @Override findClass(String name)83 protected Class<?> findClass(String name) throws ClassNotFoundException { 84 if (name.startsWith("org.osgi.framework.") || name.startsWith("org.osgi.resource.")) 85 // TODO this should call findClass; but then have to use reflection!! 86 return embeddedBundleLoader.loadClass(name); 87 return super.findClass(name); 88 } 89 90 @Override findResource(String name)91 public URL findResource(String name) { 92 if (name.startsWith("org/osgi/framework/") || name.startsWith("org/osgi/resource/")) 93 // TODO this should call findResource; but then have to use reflection!! 94 return embeddedBundleLoader.getResource(name); 95 return super.findResource(name); 96 } 97 98 @Override findResources(String name)99 public Enumeration<URL> findResources(String name) throws IOException { 100 if (name.startsWith("org/osgi/framework/") || name.startsWith("org/osgi/resource/")) 101 // TODO this should call findResources; but then have to use reflection!! 102 return embeddedBundleLoader.getResources(name); 103 return super.findResources(name); 104 } 105 106 } 107 } 108