Added support for several bundle packaging and distribution schemes (jars and class folders, distribution and development workspace). Changed the RCP sample to use the node-launcher.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@697650 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
5b2c0562e8
commit
a770a0cd29
12 changed files with 819 additions and 739 deletions
|
@ -119,8 +119,10 @@ public class EquinoxServiceDiscoverer implements ServiceDiscoverer {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty static method to trigger the activation of this bundle.
|
||||
*/
|
||||
public static void init() {
|
||||
// Empty static method to trigger the activation of this bundle
|
||||
}
|
||||
|
||||
private static String toString(Bundle b) {
|
||||
|
|
|
@ -19,20 +19,24 @@
|
|||
|
||||
package org.apache.tuscany.sca.node.equinox.launcher;
|
||||
|
||||
import static org.apache.tuscany.sca.node.equinox.launcher.NodeLauncherUtil.bundleLocation;
|
||||
import static org.apache.tuscany.sca.node.equinox.launcher.NodeLauncherUtil.installBundle;
|
||||
import static java.lang.System.currentTimeMillis;
|
||||
import static java.lang.System.setProperty;
|
||||
import static org.apache.tuscany.sca.node.equinox.launcher.NodeLauncherUtil.bundleName;
|
||||
import static org.apache.tuscany.sca.node.equinox.launcher.NodeLauncherUtil.file;
|
||||
import static org.apache.tuscany.sca.node.equinox.launcher.NodeLauncherUtil.fixupBundle;
|
||||
import static org.apache.tuscany.sca.node.equinox.launcher.NodeLauncherUtil.runtimeClasspathEntries;
|
||||
import static org.apache.tuscany.sca.node.equinox.launcher.NodeLauncherUtil.string;
|
||||
import static org.osgi.framework.Constants.BUNDLE_SYMBOLICNAME;
|
||||
import static org.apache.tuscany.sca.node.equinox.launcher.NodeLauncherUtil.thirdPartyLibraryBundle;
|
||||
import static org.apache.tuscany.sca.node.equinox.launcher.NodeLauncherUtil.thisBundleLocation;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.Manifest;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
@ -49,10 +53,16 @@ public class EquinoxHost {
|
|||
|
||||
private BundleContext bundleContext;
|
||||
private Bundle launcherBundle;
|
||||
private EquinoxLauncherBundleHelper launcherActivator;
|
||||
private boolean startedEclipse;
|
||||
private List<String> bundleFiles = new ArrayList<String>();
|
||||
private List<String> bundleNames = new ArrayList<String>();
|
||||
private List<String> jarFiles = new ArrayList<String>();
|
||||
private Map<String, Bundle> allBundles = new HashMap<String, Bundle>();
|
||||
private List<Bundle> installedBundles = new ArrayList<Bundle>();
|
||||
|
||||
private final static String systemPackages =
|
||||
"org.osgi.framework; version=1.3.0," + "org.osgi.service.packageadmin; version=1.2.0, "
|
||||
"org.osgi.framework; version=1.3.0,"
|
||||
+ "org.osgi.service.packageadmin; version=1.2.0, "
|
||||
+ "org.osgi.service.startlevel; version=1.0.0, "
|
||||
+ "org.osgi.service.url; version=1.0.0, "
|
||||
+ "org.osgi.util.tracker; version=1.3.2, "
|
||||
|
@ -67,8 +77,8 @@ public class EquinoxHost {
|
|||
+ "javax.xml.validation, "
|
||||
+ "javax.xml.xpath, "
|
||||
// Force the classes to be imported from the system bundle
|
||||
// + "javax.xml.stream, "
|
||||
// + "javax.xml.stream.util, "
|
||||
+ "javax.xml.stream, "
|
||||
+ "javax.xml.stream.util, "
|
||||
+ "javax.sql,"
|
||||
+ "org.w3c.dom, "
|
||||
+ "org.xml.sax, "
|
||||
|
@ -88,91 +98,187 @@ public class EquinoxHost {
|
|||
+ "javax.net.ssl, "
|
||||
+ "javax.crypto, "
|
||||
+ "javax.rmi, "
|
||||
+ "javax.transaction, "
|
||||
+ "javax.transaction.xa";
|
||||
|
||||
//+ "javax.transaction, "
|
||||
//+ "javax.transaction.xa, "
|
||||
+ "org.omg.CosNaming, "
|
||||
+ "org.omg.CORBA, "
|
||||
+ "org.omg.CORBA.portable, "
|
||||
+ "org.omg.PortableServer, "
|
||||
+ "org.omg.CosNaming, "
|
||||
+ "org.omg.CosNaming.NamingContextExtPackage, "
|
||||
+ "org.omg.CosNaming.NamingContextPackage, "
|
||||
+ "org.omg.CORBA_2_3.portable, "
|
||||
+ "org.omg.IOP, "
|
||||
+ "org.omg.PortableInterceptor, "
|
||||
+ "org.omg.stub.java.rmi, "
|
||||
+ "javax.rmi.CORBA";
|
||||
|
||||
/**
|
||||
* Start the Equinox host.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public BundleContext start() {
|
||||
try {
|
||||
// Configure Eclipse properties
|
||||
Map<Object, Object> props = new HashMap<Object, Object>();
|
||||
|
||||
// Set system packages
|
||||
props.put("org.osgi.framework.system.packages", systemPackages);
|
||||
if (!EclipseStarter.isRunning()) {
|
||||
|
||||
// Use the boot classloader as the parent classloader
|
||||
props.put("osgi.contextClassLoaderParent", "boot");
|
||||
|
||||
// Set startup properties
|
||||
props.put(EclipseStarter.PROP_CLEAN, "true");
|
||||
|
||||
if (logger.isLoggable(Level.FINE)) {
|
||||
props.put("osgi.console", "8085");
|
||||
}
|
||||
|
||||
// Set location properties
|
||||
// FIXME Use proper locations
|
||||
props.put(LocationManager.PROP_INSTANCE_AREA, new File("target/workspace").toURI().toString());
|
||||
props.put(LocationManager.PROP_INSTALL_AREA, new File("target/eclipse/install").toURI().toString());
|
||||
props.put(LocationManager.PROP_CONFIG_AREA, new File("target/eclipse/config").toURI().toString());
|
||||
props.put(LocationManager.PROP_USER_AREA, new File("target/eclipse/user").toURI().toString());
|
||||
|
||||
// Find the Tuscany JARs
|
||||
File tuscanyInstallDir = findTuscanyInstallDir();
|
||||
List<URL> urls;
|
||||
if (tuscanyInstallDir != null) {
|
||||
urls = JarFileFinder.findJarFiles(tuscanyInstallDir, new JarFileFinder.StandAloneJARFileNameFilter());
|
||||
// Configure Eclipse properties
|
||||
Map<Object, Object> props = new HashMap<Object, Object>();
|
||||
|
||||
// Set system packages
|
||||
props.put("org.osgi.framework.system.packages", systemPackages);
|
||||
|
||||
// Use the boot classloader as the parent classloader
|
||||
props.put("osgi.contextClassLoaderParent", "boot");
|
||||
|
||||
// Set startup properties
|
||||
props.put(EclipseStarter.PROP_CLEAN, "true");
|
||||
|
||||
if (logger.isLoggable(Level.FINE)) {
|
||||
props.put("osgi.console", "8085");
|
||||
}
|
||||
|
||||
// Set location properties
|
||||
// FIXME Use proper locations
|
||||
props.put(LocationManager.PROP_INSTANCE_AREA, new File("target/workspace").toURI().toString());
|
||||
props.put(LocationManager.PROP_INSTALL_AREA, new File("target/eclipse/install").toURI().toString());
|
||||
props.put(LocationManager.PROP_CONFIG_AREA, new File("target/eclipse/config").toURI().toString());
|
||||
props.put(LocationManager.PROP_USER_AREA, new File("target/eclipse/user").toURI().toString());
|
||||
|
||||
EclipseStarter.setInitialProperties(props);
|
||||
|
||||
// Start Eclipse
|
||||
bundleContext = EclipseStarter.startup(new String[]{}, null);
|
||||
startedEclipse = true;
|
||||
|
||||
} else {
|
||||
urls = JarFileFinder.getClassPathEntries(JarFileFinder.class.getClassLoader(), false);
|
||||
|
||||
// Get bundle context from the running Eclipse instance
|
||||
bundleContext = EclipseStarter.getSystemBundleContext();
|
||||
}
|
||||
|
||||
// Determine the runtime classpath entries
|
||||
Set<URL> urls = runtimeClasspathEntries();
|
||||
|
||||
// Sort out which are bundles (and not already installed) and which are just
|
||||
// regular JARs
|
||||
StringBuffer bundleFiles = new StringBuffer();
|
||||
StringBuffer bundleNames = new StringBuffer();
|
||||
StringBuffer jarFiles = new StringBuffer();
|
||||
for (URL url : urls) {
|
||||
File file = NodeLauncherUtil.file(url);
|
||||
String bundleName = getBundleName(file);
|
||||
File file = file(url);
|
||||
String bundleName = bundleName(file);
|
||||
if (bundleName != null) {
|
||||
bundleFiles.append(url.toString() + ";");
|
||||
bundleNames.append(bundleName + ";");
|
||||
bundleFiles.add(url.toString());
|
||||
bundleNames.add(bundleName);
|
||||
} else {
|
||||
if (file.isFile()) {
|
||||
jarFiles.append(url.toString() + ";");
|
||||
jarFiles.add(url.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
props.put("org.apache.tuscany.sca.node.launcher.equinox.bundleFiles", bundleFiles.toString());
|
||||
props.put("org.apache.tuscany.sca.node.launcher.equinox.bundleNames", bundleNames.toString());
|
||||
props.put("org.apache.tuscany.sca.node.launcher.equinox.jarFiles", jarFiles.toString());
|
||||
|
||||
EclipseStarter.setInitialProperties(props);
|
||||
|
||||
// Start Eclipse
|
||||
bundleContext = EclipseStarter.startup(new String[]{}, null);
|
||||
|
||||
// Install the launcher bundle
|
||||
String bundleLocation = bundleLocation();
|
||||
logger.info("Installing launcher bundle: " + bundleLocation);
|
||||
launcherBundle = installBundle(bundleContext, bundleLocation);
|
||||
logger.info("Starting bundle: " + string(launcherBundle, false));
|
||||
launcherBundle.start();
|
||||
|
||||
// Manually call the LauncherBundleActivator for now
|
||||
launcherActivator = new EquinoxLauncherBundleHelper();
|
||||
launcherActivator.start(launcherBundle.getBundleContext());
|
||||
|
||||
// Start all bundles for now to help diagnose any class loading issues
|
||||
long activateStart = System.currentTimeMillis();
|
||||
|
||||
// Get the already installed bundles
|
||||
for (Bundle bundle: bundleContext.getBundles()) {
|
||||
if ((bundle.getState() & Bundle.ACTIVE) == 0) {
|
||||
logger.info("Starting bundle: " + string(bundle, false));
|
||||
try {
|
||||
bundle.start();
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, e.getMessage(), e);
|
||||
allBundles.put(bundle.getSymbolicName(), bundle);
|
||||
}
|
||||
|
||||
// Install the launcher bundle if necessary
|
||||
String launcherBundleName = "org.apache.tuscany.sca.node.launcher.equinox";
|
||||
String launcherBundleLocation;
|
||||
launcherBundle = allBundles.get(launcherBundleName);
|
||||
if (launcherBundle == null) {
|
||||
launcherBundleLocation = thisBundleLocation();
|
||||
logger.info("Installing launcher bundle: " + launcherBundleLocation);
|
||||
fixupBundle(launcherBundleLocation);
|
||||
launcherBundle = bundleContext.installBundle(launcherBundleLocation);
|
||||
allBundles.put(launcherBundleName, launcherBundle);
|
||||
installedBundles.add(launcherBundle);
|
||||
} else {
|
||||
logger.info("Launcher bundle is already installed: " + string(launcherBundle, false));
|
||||
launcherBundleLocation = thisBundleLocation(launcherBundle);
|
||||
}
|
||||
|
||||
// Install the Tuscany bundles
|
||||
long start = currentTimeMillis();
|
||||
|
||||
// FIXME: SDO bundles dont have the correct dependencies
|
||||
setProperty("commonj.sdo.impl.HelperProvider", "org.apache.tuscany.sdo.helper.HelperProviderImpl");
|
||||
|
||||
// Install a single 'library' bundle for the third-party JAR files
|
||||
String libraryBundleName = "org.apache.tuscany.sca.node.launcher.equinox.libraries";
|
||||
Bundle libraryBundle = allBundles.get(libraryBundleName);
|
||||
if (libraryBundle == null) {
|
||||
logger.info("Generating third-party library bundle.");
|
||||
for (String jarFile: jarFiles) {
|
||||
logger.info("Adding third-party jar: " + jarFile);
|
||||
}
|
||||
long libraryStart = currentTimeMillis();
|
||||
InputStream library = thirdPartyLibraryBundle(jarFiles);
|
||||
logger.info("Third-party library bundle generated in " + (currentTimeMillis() - libraryStart) + " ms.");
|
||||
libraryStart = currentTimeMillis();
|
||||
libraryBundle = bundleContext.installBundle("org.apache.tuscany.sca.node.launcher.equinox.libraries", library);
|
||||
allBundles.put(libraryBundleName, libraryBundle);
|
||||
installedBundles.add(libraryBundle);
|
||||
logger.info("Third-party library bundle installed in " + (currentTimeMillis() - libraryStart) + " ms: " + string(libraryBundle, false));
|
||||
} else {
|
||||
logger.info("Third-party library bundle is already installed: " + string(libraryBundle, false));
|
||||
}
|
||||
|
||||
// Install all the other bundles that are not already installed
|
||||
for (int i =0, n = bundleFiles.size(); i < n; i++) {
|
||||
String bundleFile = bundleFiles.get(i);
|
||||
fixupBundle(bundleFile);
|
||||
}
|
||||
for (int i =0, n = bundleFiles.size(); i < n; i++) {
|
||||
String bundleFile = bundleFiles.get(i);
|
||||
String bundleName = bundleNames.get(i);
|
||||
if (bundleName.contains("org.eclipse.jdt.junit")) {
|
||||
continue;
|
||||
}
|
||||
if (bundleName.contains("host.openejb")) {
|
||||
continue;
|
||||
}
|
||||
Bundle bundle = allBundles.get(bundleName);
|
||||
if (bundle == null) {
|
||||
long installStart = currentTimeMillis();
|
||||
bundle = bundleContext.installBundle(bundleFile);
|
||||
logger.info("Bundle installed in " + (currentTimeMillis() - installStart) + " ms: " + string(bundle, false));
|
||||
allBundles.put(bundleName, bundle);
|
||||
installedBundles.add(bundle);
|
||||
}
|
||||
}
|
||||
|
||||
long end = currentTimeMillis();
|
||||
logger.info("Tuscany bundles are installed in " + (end - start) + " ms.");
|
||||
|
||||
// Start the extensiblity and launcher bundles
|
||||
long activateStart = System.currentTimeMillis();
|
||||
String extensibilityBundleName = "org.apache.tuscany.sca.extensibility.equinox";
|
||||
Bundle extensibilityBundle = allBundles.get(extensibilityBundleName);
|
||||
if ((extensibilityBundle.getState() & Bundle.ACTIVE) == 0) {
|
||||
logger.info("Starting bundle: " + string(extensibilityBundle, false));
|
||||
extensibilityBundle.start();
|
||||
} else {
|
||||
logger.info("Bundle is already started: " + string(extensibilityBundle, false));
|
||||
}
|
||||
if ((launcherBundle.getState() & Bundle.ACTIVE) == 0) {
|
||||
logger.info("Starting bundle: " + string(launcherBundle, false));
|
||||
launcherBundle.start();
|
||||
} else {
|
||||
logger.info("Bundle is already started: " + string(launcherBundle, false));
|
||||
}
|
||||
|
||||
// Start all our bundles for now to help diagnose any class loading issues
|
||||
for (Bundle bundle: bundleContext.getBundles()) {
|
||||
if (bundle.getSymbolicName().startsWith("org.apache.tuscany.sca")) {
|
||||
if ((bundle.getState() & Bundle.ACTIVE) == 0) {
|
||||
logger.info("Starting bundle: " + string(bundle, false));
|
||||
try {
|
||||
bundle.start();
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, e.getMessage(), e);
|
||||
throw e;
|
||||
}
|
||||
logger.info("Bundle: " + string(bundle, false));
|
||||
}
|
||||
logger.info("Bundle: " + string(bundle, false));
|
||||
}
|
||||
}
|
||||
logger.info("Tuscany bundles are started in " + (System.currentTimeMillis() - activateStart) + " ms.");
|
||||
|
@ -182,78 +288,36 @@ public class EquinoxHost {
|
|||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Stop the Equinox host.
|
||||
*/
|
||||
public void stop() {
|
||||
try {
|
||||
|
||||
// Uninstall the launcher bundle
|
||||
if (launcherActivator != null) {
|
||||
launcherActivator.stop(launcherBundle.getBundleContext());
|
||||
// Uninstall all the bundles we've installed
|
||||
for (int i = installedBundles.size() -1; i >= 0; i--) {
|
||||
Bundle bundle = installedBundles.get(i);
|
||||
try {
|
||||
//if (logger.isLoggable(Level.FINE)) {
|
||||
logger.info("Uninstalling bundle: " + string(bundle, false));
|
||||
//}
|
||||
bundle.uninstall();
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
if (launcherBundle != null) {
|
||||
logger.info("Uninstalling bundle: " + string(launcherBundle, false));
|
||||
launcherBundle.uninstall();
|
||||
installedBundles.clear();
|
||||
|
||||
// Shutdown Eclipse if we started it ourselves
|
||||
if (startedEclipse) {
|
||||
startedEclipse = false;
|
||||
EclipseStarter.shutdown();
|
||||
}
|
||||
|
||||
// Shutdown Eclipse
|
||||
EclipseStarter.shutdown();
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static File findTuscanyInstallDir() throws IOException {
|
||||
String tuscanyDirName = JarFileFinder.getProperty(JarFileFinder.TUSCANY_HOME);
|
||||
if (tuscanyDirName != null) {
|
||||
File tuscanyInstallDir = new File(tuscanyDirName);
|
||||
if (tuscanyInstallDir.exists() && tuscanyInstallDir.isDirectory())
|
||||
return tuscanyInstallDir;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of a bundle, or null if the given file is not a bundle.
|
||||
*
|
||||
* @param file
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
private static String getBundleName(File file) throws IOException {
|
||||
if (!file.exists()) {
|
||||
return null;
|
||||
}
|
||||
String bundleName = null;
|
||||
if (file.isDirectory()) {
|
||||
File mf = new File(file, "META-INF/MANIFEST.MF");
|
||||
if (mf.isFile()) {
|
||||
Manifest manifest = new Manifest(new FileInputStream(mf));
|
||||
bundleName = manifest.getMainAttributes().getValue(BUNDLE_SYMBOLICNAME);
|
||||
} else {
|
||||
if (file.getPath().endsWith("target/classes")) {
|
||||
// Development mode, MANIFEST.MF is outside the bundle location
|
||||
mf = new File(file.getParentFile().getParentFile(), "META-INF/MANIFEST.MF");
|
||||
if (mf.isFile()) {
|
||||
Manifest manifest = new Manifest(new FileInputStream(mf));
|
||||
bundleName = manifest.getMainAttributes().getValue(BUNDLE_SYMBOLICNAME);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
JarFile jar = new JarFile(file, false);
|
||||
Manifest manifest = jar.getManifest();
|
||||
bundleName = manifest.getMainAttributes().getValue(BUNDLE_SYMBOLICNAME);
|
||||
jar.close();
|
||||
}
|
||||
if (bundleName == null) {
|
||||
return bundleName;
|
||||
}
|
||||
int sc = bundleName.indexOf(';');
|
||||
if (sc != -1) {
|
||||
bundleName = bundleName.substring(0, sc);
|
||||
}
|
||||
return bundleName;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,119 +0,0 @@
|
|||
package org.apache.tuscany.sca.node.equinox.launcher;
|
||||
|
||||
import static java.lang.System.currentTimeMillis;
|
||||
import static java.lang.System.getProperty;
|
||||
import static java.lang.System.setProperty;
|
||||
import static org.apache.tuscany.sca.node.equinox.launcher.NodeLauncherUtil.installBundle;
|
||||
import static org.apache.tuscany.sca.node.equinox.launcher.NodeLauncherUtil.libraryBundle;
|
||||
import static org.apache.tuscany.sca.node.equinox.launcher.NodeLauncherUtil.string;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.BundleEvent;
|
||||
import org.osgi.framework.BundleListener;
|
||||
|
||||
/**
|
||||
* Bundle activator which installs Tuscany modules into an OSGi runtime.
|
||||
*
|
||||
*/
|
||||
public class EquinoxLauncherBundleHelper implements BundleListener {
|
||||
private static Logger logger = Logger.getLogger(EquinoxLauncherBundleHelper.class.getName());
|
||||
|
||||
private List<Bundle> installedBundles = new ArrayList<Bundle>();
|
||||
private BundleContext bundleContext;
|
||||
|
||||
public EquinoxLauncherBundleHelper() {
|
||||
super();
|
||||
}
|
||||
|
||||
public void start(BundleContext bundleContext) throws Exception {
|
||||
this.bundleContext = bundleContext;
|
||||
this.bundleContext.addBundleListener(this);
|
||||
|
||||
// Install the Tuscany bundles
|
||||
long start = currentTimeMillis();
|
||||
|
||||
// FIXME: SDO bundles dont have the correct dependencies
|
||||
setProperty("commonj.sdo.impl.HelperProvider", "org.apache.tuscany.sdo.helper.HelperProviderImpl");
|
||||
|
||||
// Get the list of JAR files to install
|
||||
String jarFilesProperty = getProperty("org.apache.tuscany.sca.node.launcher.equinox.jarFiles");
|
||||
String[] jarFiles = jarFilesProperty.split(";");
|
||||
|
||||
// Create a single 'library' bundle for them
|
||||
logger.info("Generating third-party library bundle.");
|
||||
for (String jarFile: jarFiles) {
|
||||
logger.info("Adding third-party jar: " + jarFile);
|
||||
}
|
||||
long libraryStart = currentTimeMillis();
|
||||
InputStream library = libraryBundle(jarFiles);
|
||||
logger.info("Third-party library bundle generated in " + (currentTimeMillis() - libraryStart) + " ms.");
|
||||
libraryStart = currentTimeMillis();
|
||||
Bundle libraryBundle = bundleContext.installBundle("org.apache.tuscany.sca.node.launcher.equinox.libraries", library);
|
||||
logger.info("Third-party library bundle installed in " + (currentTimeMillis() - libraryStart) + " ms: " + string(libraryBundle, false));
|
||||
installedBundles.add(libraryBundle);
|
||||
|
||||
// Get the set of already installed bundles
|
||||
Set<String> alreadyInstalledBundleNames = new HashSet<String>();
|
||||
for (Bundle bundle: bundleContext.getBundles()) {
|
||||
alreadyInstalledBundleNames.add(bundle.getSymbolicName());
|
||||
}
|
||||
|
||||
// Get the list of bundle files and names to install
|
||||
String bundleFilesProperty = getProperty("org.apache.tuscany.sca.node.launcher.equinox.bundleFiles");
|
||||
String[] bundleFiles = bundleFilesProperty.split(";");
|
||||
String bundleNamesProperty = getProperty("org.apache.tuscany.sca.node.launcher.equinox.bundleNames");
|
||||
String[] bundleNames = bundleNamesProperty.split(";");
|
||||
|
||||
// Install all the bundles that are not already installed
|
||||
for (int i =0, n = bundleFiles.length; i < n; i++) {
|
||||
String bundleFile = bundleFiles[i];
|
||||
String bundleName = bundleNames[i];
|
||||
if (!alreadyInstalledBundleNames.contains(bundleName)) {
|
||||
if (bundleName.contains("org.eclipse.jdt.junit")) {
|
||||
continue;
|
||||
}
|
||||
long installStart = currentTimeMillis();
|
||||
Bundle bundle = installBundle(bundleContext, bundleFile);
|
||||
logger.info("Bundle installed in " + (currentTimeMillis() - installStart) + " ms: " + string(bundle, false));
|
||||
installedBundles.add(bundle);
|
||||
alreadyInstalledBundleNames.add(bundleName);
|
||||
}
|
||||
}
|
||||
|
||||
long end = currentTimeMillis();
|
||||
logger.info("Tuscany bundles are installed in " + (end - start) + " ms.");
|
||||
}
|
||||
|
||||
public void stop(BundleContext bundleContext) throws Exception {
|
||||
|
||||
// Uninstall all the bundles we've installed
|
||||
for (int i = installedBundles.size() -1; i >= 0; i--) {
|
||||
Bundle bundle = installedBundles.get(i);
|
||||
try {
|
||||
//if (logger.isLoggable(Level.FINE)) {
|
||||
logger.info("Uninstalling bundle: " + string(bundle, false));
|
||||
//}
|
||||
bundle.uninstall();
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
installedBundles.clear();
|
||||
|
||||
this.bundleContext.removeBundleListener(this);
|
||||
this.bundleContext = null;
|
||||
}
|
||||
|
||||
public void bundleChanged(BundleEvent event) {
|
||||
}
|
||||
|
||||
}
|
|
@ -1,373 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.tuscany.sca.node.equinox.launcher;
|
||||
|
||||
import static org.apache.tuscany.sca.node.equinox.launcher.NodeLauncherUtil.file;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class JarFileFinder {
|
||||
/**
|
||||
* A file name filter used to filter JAR files.
|
||||
*/
|
||||
static class StandAloneJARFileNameFilter implements FilenameFilter {
|
||||
|
||||
public boolean accept(File dir, String name) {
|
||||
name = name.toLowerCase();
|
||||
|
||||
// Exclude tuscany-sca-all and tuscany-sca-manifest as they duplicate
|
||||
// code in the individual runtime module JARs
|
||||
if (name.startsWith("tuscany-sca-all")) {
|
||||
return false;
|
||||
}
|
||||
if (name.startsWith("tuscany-sca-manifest")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Filter out the Tomcat and Webapp hosts
|
||||
if (name.startsWith("tuscany-host-tomcat") || name.startsWith("tuscany-host-webapp")) {
|
||||
//FIXME This is temporary
|
||||
return false;
|
||||
}
|
||||
|
||||
// Include JAR and MAR files
|
||||
if (name.endsWith(".jar")) {
|
||||
return true;
|
||||
}
|
||||
if (name.endsWith(".mar")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A file name filter used to filter JAR files.
|
||||
*/
|
||||
static class WebAppJARFileNameFilter extends StandAloneJARFileNameFilter {
|
||||
|
||||
public boolean accept(File dir, String name) {
|
||||
if (!super.accept(dir, name)) {
|
||||
return false;
|
||||
}
|
||||
name = name.toLowerCase();
|
||||
|
||||
// Exclude servlet-api JARs
|
||||
if (name.startsWith("servlet-api")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Exclude the Tomcat and Jetty hosts
|
||||
if (name.startsWith("tuscany-host-tomcat") || name.startsWith("tuscany-host-jetty")) {
|
||||
//FIXME This is temporary
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private static final Logger logger = Logger.getLogger(JarFileFinder.class.getName());
|
||||
|
||||
static final String TUSCANY_HOME = "TUSCANY_HOME";
|
||||
private static final String TUSCANY_PATH = "TUSCANY_PATH";
|
||||
|
||||
/**
|
||||
* Collect JAR files in the given directory
|
||||
* @param directory
|
||||
* @param urls
|
||||
* @param filter
|
||||
* @throws MalformedURLException
|
||||
*/
|
||||
private static void collectJARFiles(File directory, List<URL> urls, FilenameFilter filter)
|
||||
throws MalformedURLException {
|
||||
String[] files = directory.list(filter);
|
||||
if (files != null) {
|
||||
URL directoryURL = new URL(directory.toURI().toString() + "/");
|
||||
int count = 0;
|
||||
for (String file : files) {
|
||||
URL url = new URL(directoryURL, file);
|
||||
urls.add(url);
|
||||
count++;
|
||||
}
|
||||
if (count != 0) {
|
||||
logger.fine("Runtime classpath: " + count
|
||||
+ " JAR"
|
||||
+ (count > 1 ? "s" : "")
|
||||
+ " from "
|
||||
+ directory.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect JAR files under the given directory.
|
||||
*
|
||||
* @param directory
|
||||
* @param jarDirectoryURLs
|
||||
* @param jarURLs
|
||||
* @param filter
|
||||
* @throws MalformedURLException
|
||||
*/
|
||||
private static void collectJARFiles(String directory,
|
||||
Set<URL> jarDirectoryURLs,
|
||||
List<URL> jarURLs,
|
||||
FilenameFilter filter) throws MalformedURLException {
|
||||
File directoryFile = new File(directory);
|
||||
URL directoryURL = directoryFile.toURI().toURL();
|
||||
if (!jarDirectoryURLs.contains(directoryURL) && directoryFile.exists()) {
|
||||
|
||||
// Collect files under $TUSCANY_HOME
|
||||
jarDirectoryURLs.add(directoryURL);
|
||||
collectJARFiles(directoryFile, jarURLs, filter);
|
||||
|
||||
// Collect files under $TUSCANY_HOME/modules
|
||||
File modulesDirectory = new File(directoryFile, "modules");
|
||||
URL modulesDirectoryURL = modulesDirectory.toURI().toURL();
|
||||
if (!jarDirectoryURLs.contains(modulesDirectoryURL) && modulesDirectory.exists()) {
|
||||
jarDirectoryURLs.add(modulesDirectoryURL);
|
||||
collectJARFiles(modulesDirectory, jarURLs, filter);
|
||||
}
|
||||
|
||||
// Collect files under $TUSCANY_HOME/lib
|
||||
File libDirectory = new File(directoryFile, "lib");
|
||||
URL libDirectoryURL = libDirectory.toURI().toURL();
|
||||
if (!jarDirectoryURLs.contains(libDirectoryURL) && libDirectory.exists()) {
|
||||
jarDirectoryURLs.add(libDirectoryURL);
|
||||
collectJARFiles(libDirectory, jarURLs, filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a ClassLoader for the Tuscany runtime JARs.
|
||||
*
|
||||
* @param parentClassLoader
|
||||
* @param filter
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static List<URL> findJarFiles(File root, FilenameFilter filter) throws FileNotFoundException,
|
||||
URISyntaxException, MalformedURLException {
|
||||
|
||||
// Build list of runtime JARs
|
||||
Set<URL> jarDirectoryURLs = new HashSet<URL>();
|
||||
List<URL> jarURLs = new ArrayList<URL>();
|
||||
|
||||
URL url = null;
|
||||
if (root != null) {
|
||||
url = root.toURI().toURL();
|
||||
} else {
|
||||
// First determine the path to the launcher class
|
||||
String resource = JarFileFinder.class.getName().replace('.', '/') + ".class";
|
||||
url = JarFileFinder.class.getClassLoader().getResource(resource);
|
||||
if (url == null) {
|
||||
throw new FileNotFoundException(resource);
|
||||
}
|
||||
|
||||
url = getContainer(url, resource);
|
||||
}
|
||||
URI uri = url.toURI();
|
||||
|
||||
// If the launcher class is in a JAR, add all runtime JARs from directory containing
|
||||
// that JAR (e.g. the Tuscany modules directory) as well as the ../modules and
|
||||
// ../lib directories
|
||||
if (url != null && "file".equals(url.getProtocol())) {
|
||||
|
||||
File file = new File(uri);
|
||||
if (file.exists()) {
|
||||
File jarDirectory = file.getParentFile();
|
||||
if (jarDirectory != null && jarDirectory.exists()) {
|
||||
|
||||
// Collect JAR files from the directory containing the input JAR
|
||||
// (e.g. the Tuscany modules directory)
|
||||
URL jarDirectoryURL = jarDirectory.toURI().toURL();
|
||||
jarDirectoryURLs.add(jarDirectoryURL);
|
||||
collectJARFiles(jarDirectory, jarURLs, filter);
|
||||
|
||||
File homeDirectory = jarDirectory.getParentFile();
|
||||
if (homeDirectory != null && homeDirectory.exists()) {
|
||||
|
||||
// Collect JARs from the ../modules directory
|
||||
File modulesDirectory = new File(homeDirectory, "modules");
|
||||
URL modulesDirectoryURL = modulesDirectory.toURI().toURL();
|
||||
if (!jarDirectoryURLs.contains(modulesDirectoryURL) && modulesDirectory.exists()) {
|
||||
jarDirectoryURLs.add(modulesDirectoryURL);
|
||||
collectJARFiles(modulesDirectory, jarURLs, filter);
|
||||
}
|
||||
|
||||
// Collect JARs from the ../lib directory
|
||||
File libDirectory = new File(homeDirectory, "lib");
|
||||
URL libDirectoryURL = libDirectory.toURI().toURL();
|
||||
if (!jarDirectoryURLs.contains(libDirectoryURL) && libDirectory.exists()) {
|
||||
jarDirectoryURLs.add(libDirectoryURL);
|
||||
collectJARFiles(libDirectory, jarURLs, filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Look for a TUSCANY_HOME system property or environment variable
|
||||
// Add all the JARs found under $TUSCANY_HOME, $TUSCANY_HOME/modules
|
||||
// and $TUSCANY_HOME/lib
|
||||
String home = getProperty(TUSCANY_HOME);
|
||||
if (home != null && home.length() != 0) {
|
||||
logger.fine(TUSCANY_HOME + ": " + home);
|
||||
collectJARFiles(home, jarDirectoryURLs, jarURLs, filter);
|
||||
}
|
||||
|
||||
// Look for a TUSCANY_PATH system property or environment variable
|
||||
// Add all the JARs found under $TUSCANY_PATH, $TUSCANY_PATH/modules
|
||||
// and $TUSCANY_PATH/lib
|
||||
String ext = getProperty(TUSCANY_PATH);
|
||||
if (ext != null && ext.length() != 0) {
|
||||
logger.fine(TUSCANY_PATH + ": " + ext);
|
||||
String separator = getProperty("path.separator");
|
||||
for (StringTokenizer tokens = new StringTokenizer(ext, separator); tokens.hasMoreTokens();) {
|
||||
collectJARFiles(tokens.nextToken(), jarDirectoryURLs, jarURLs, filter);
|
||||
}
|
||||
}
|
||||
|
||||
return jarURLs;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns contribution JARs available on the classpath.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
static List<URL> getClassPathEntries(ClassLoader classLoader, boolean recursive) {
|
||||
Set<URL> entries = new HashSet<URL>();
|
||||
list(entries, classLoader, recursive);
|
||||
return new ArrayList<URL>(entries);
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect JARs on the classpath of a URLClassLoader
|
||||
* @param urls
|
||||
* @param cl
|
||||
*/
|
||||
private static void list(Set<URL> urls, ClassLoader cl, boolean recursive) {
|
||||
if (cl == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Collect JARs from the URLClassLoader's classpath
|
||||
if (cl instanceof URLClassLoader) {
|
||||
URL[] jarURLs = ((URLClassLoader)cl).getURLs();
|
||||
if (jarURLs != null) {
|
||||
for (URL jarURL : jarURLs) {
|
||||
urls.add(jarURL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Collect JARs from the parent ClassLoader
|
||||
if (recursive) {
|
||||
list(urls, cl.getParent(), recursive);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static String getProperty(final String prop) {
|
||||
return AccessController.doPrivileged(new PrivilegedAction<String>() {
|
||||
public String run() {
|
||||
String value = System.getProperty(prop);
|
||||
if (value == null || value.length() == 0) {
|
||||
return System.getenv(prop);
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static URL getContainer(URL resourceURL, String resourceName) {
|
||||
URL root = null;
|
||||
// "jar:file://....../something.jar!/a/b/c/app.composite"
|
||||
try {
|
||||
String url = resourceURL.toExternalForm();
|
||||
String protocol = resourceURL.getProtocol();
|
||||
if ("file".equals(protocol)) {
|
||||
// directory contribution
|
||||
if (url.endsWith("/" + resourceName)) {
|
||||
final String location = url.substring(0, url.length() - resourceName.length() - 1);
|
||||
// workaround from evil URL/URI form Maven
|
||||
// contributionURL = FileHelper.toFile(new URL(location)).toURI().toURL();
|
||||
// Allow privileged access to open URL stream. Add FilePermission to added to
|
||||
// security policy file.
|
||||
try {
|
||||
root = AccessController.doPrivileged(new PrivilegedExceptionAction<URL>() {
|
||||
public URL run() throws IOException {
|
||||
return file(new URL(location)).toURI().toURL();
|
||||
}
|
||||
});
|
||||
} catch (PrivilegedActionException e) {
|
||||
throw (MalformedURLException)e.getException();
|
||||
}
|
||||
}
|
||||
|
||||
} else if ("jar".equals(protocol)) {
|
||||
// jar contribution
|
||||
String location = url.substring(4, url.lastIndexOf("!/"));
|
||||
// workaround for evil URL/URI from Maven
|
||||
root = file(new URL(location)).toURI().toURL();
|
||||
|
||||
} else if ("wsjar".equals(protocol)) {
|
||||
// See https://issues.apache.org/jira/browse/TUSCANY-2219
|
||||
// wsjar contribution
|
||||
String location = url.substring(6, url.lastIndexOf("!/"));
|
||||
// workaround for evil url/uri from maven
|
||||
root = file(new URL(location)).toURI().toURL();
|
||||
|
||||
} else if (protocol != null && (protocol.equals("bundle") || protocol.equals("bundleresource"))) {
|
||||
root = new URL(resourceURL.getProtocol(), resourceURL.getHost(), resourceURL.getPort(), "/");
|
||||
}
|
||||
} catch (MalformedURLException mfe) {
|
||||
throw new IllegalArgumentException(mfe);
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
}
|
|
@ -35,15 +35,15 @@ import org.osgi.framework.BundleContext;
|
|||
public class NodeLauncher {
|
||||
|
||||
static final Logger logger = Logger.getLogger(NodeLauncher.class.getName());
|
||||
private EquinoxHost host;
|
||||
private EquinoxHost equinoxHost;
|
||||
private BundleContext bundleContext;
|
||||
|
||||
/**
|
||||
* Constructs a new node launcher.
|
||||
*/
|
||||
private NodeLauncher() {
|
||||
host = new EquinoxHost();
|
||||
bundleContext = host.start();
|
||||
equinoxHost = new EquinoxHost();
|
||||
bundleContext = equinoxHost.start();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -121,7 +121,7 @@ public class NodeLauncher {
|
|||
// Create a node launcher
|
||||
NodeLauncher launcher = newInstance();
|
||||
|
||||
EquinoxHost equinox = launcher.host;
|
||||
EquinoxHost equinox = launcher.equinoxHost;
|
||||
Object node = null;
|
||||
ShutdownThread shutdown = null;
|
||||
try {
|
||||
|
@ -184,8 +184,8 @@ public class NodeLauncher {
|
|||
}
|
||||
|
||||
public void destroy() {
|
||||
if (host != null) {
|
||||
host.stop();
|
||||
if (equinoxHost != null) {
|
||||
equinoxHost.stop();
|
||||
bundleContext = null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,19 +32,29 @@ import java.io.File;
|
|||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.JarOutputStream;
|
||||
import java.util.jar.Manifest;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.zip.ZipEntry;
|
||||
|
@ -60,6 +70,7 @@ import org.osgi.framework.BundleException;
|
|||
* @version $Rev$ $Date$
|
||||
*/
|
||||
final class NodeLauncherUtil {
|
||||
private static final Logger logger = Logger.getLogger(NodeLauncherUtil.class.getName());
|
||||
|
||||
private static final String LAUNCHER_EQUINOX_LIBRARIES = "org.apache.tuscany.sca.node.launcher.equinox.libraries";
|
||||
|
||||
|
@ -74,18 +85,29 @@ final class NodeLauncherUtil {
|
|||
private static final String NODE_IMPLEMENTATION_LAUNCHER_BOOTSTRAP =
|
||||
"org.apache.tuscany.sca.implementation.node.launcher.NodeImplementationLauncherBootstrap";
|
||||
|
||||
private static final String TUSCANY_HOME = "TUSCANY_HOME";
|
||||
private static final String TUSCANY_PATH = "TUSCANY_PATH";
|
||||
|
||||
/**
|
||||
* Collect JAR files under the given directory.
|
||||
* Creates a new node.
|
||||
*
|
||||
* @param configurationURI
|
||||
* @param compositeURI
|
||||
* @param compositeContent
|
||||
* @param contributions
|
||||
* @param bundleContext TODO
|
||||
* @param contributionClassLoader
|
||||
* @param bundleContext
|
||||
* @throws LauncherException
|
||||
*/
|
||||
static Object node(String configurationURI,
|
||||
String compositeURI,
|
||||
String compositeContent,
|
||||
Contribution[] contributions,
|
||||
ClassLoader contributionClassLoader, BundleContext bundleContext) throws LauncherException {
|
||||
ClassLoader contributionClassLoader,
|
||||
BundleContext bundleContext) throws LauncherException {
|
||||
try {
|
||||
|
||||
// Get the node runtime bundle.
|
||||
Bundle bundle = null;
|
||||
for (Bundle b : bundleContext.getBundles()) {
|
||||
if ("org.apache.tuscany.sca.implementation.node.runtime".equals(b.getSymbolicName())) {
|
||||
|
@ -94,9 +116,9 @@ final class NodeLauncherUtil {
|
|||
}
|
||||
}
|
||||
if (bundle == null) {
|
||||
throw new IllegalStateException(
|
||||
"Bundle org.apache.tuscany.sca.implementation.node.runtime is not installed");
|
||||
throw new IllegalStateException("Bundle org.apache.tuscany.sca.implementation.node.runtime is not installed");
|
||||
}
|
||||
|
||||
// Use Java reflection to create the node as only the runtime class
|
||||
// loader knows the runtime classes required by the node
|
||||
Class<?> bootstrapClass = bundle.loadClass(NODE_IMPLEMENTATION_LAUNCHER_BOOTSTRAP);
|
||||
|
@ -117,8 +139,7 @@ final class NodeLauncherUtil {
|
|||
|
||||
// Construct the node with a composite URI, the composite content and
|
||||
// the URIs and locations of a list of contributions
|
||||
Constructor<?> constructor =
|
||||
bootstrapClass.getConstructor(String.class, String.class, String[].class, String[].class);
|
||||
Constructor<?> constructor = bootstrapClass.getConstructor(String.class, String.class, String[].class, String[].class);
|
||||
String[] uris = new String[contributions.length];
|
||||
String[] locations = new String[contributions.length];
|
||||
for (int i = 0; i < contributions.length; i++) {
|
||||
|
@ -131,8 +152,7 @@ final class NodeLauncherUtil {
|
|||
|
||||
// Construct the node with a composite URI and the URIs and
|
||||
// locations of a list of contributions
|
||||
Constructor<?> constructor =
|
||||
bootstrapClass.getConstructor(String.class, String[].class, String[].class);
|
||||
Constructor<?> constructor = bootstrapClass.getConstructor(String.class, String[].class, String[].class);
|
||||
String[] uris = new String[contributions.length];
|
||||
String[] locations = new String[contributions.length];
|
||||
for (int i = 0; i < contributions.length; i++) {
|
||||
|
@ -142,7 +162,11 @@ final class NodeLauncherUtil {
|
|||
bootstrap = constructor.newInstance(compositeURI, uris, locations);
|
||||
}
|
||||
|
||||
// Get the node instance
|
||||
Object node = bootstrapClass.getMethod("getNode").invoke(bootstrap);
|
||||
|
||||
// If the SCANodeFactory interface is available in the current classloader, create
|
||||
// an SCANode proxy around the node we've just create
|
||||
try {
|
||||
Class<?> type = Class.forName(SCANODE_FACTORY);
|
||||
type = type.getDeclaredClasses()[0];
|
||||
|
@ -213,26 +237,15 @@ final class NodeLauncherUtil {
|
|||
}
|
||||
}
|
||||
|
||||
static File file(URL url) {
|
||||
if (url == null || !url.getProtocol().equals("file")) {
|
||||
return null;
|
||||
} else {
|
||||
String filename = url.getFile().replace('/', File.separatorChar);
|
||||
int pos = 0;
|
||||
while ((pos = filename.indexOf('%', pos)) >= 0) {
|
||||
if (pos + 2 < filename.length()) {
|
||||
String hexStr = filename.substring(pos + 1, pos + 3);
|
||||
char ch = (char)Integer.parseInt(hexStr, 16);
|
||||
filename = filename.substring(0, pos) + ch + filename.substring(pos + 3);
|
||||
}
|
||||
}
|
||||
return new File(filename);
|
||||
}
|
||||
}
|
||||
private static Pattern pattern = Pattern.compile("-([0-9.]+)");
|
||||
|
||||
static Pattern pattern = Pattern.compile("-([0-9.]+)");
|
||||
|
||||
private static String version(String jarFile) {
|
||||
/**
|
||||
* Returns the version number to use for the given JAR file.
|
||||
*
|
||||
* @param jarFile
|
||||
* @return
|
||||
*/
|
||||
private static String jarVersion(String jarFile) {
|
||||
Matcher matcher = pattern.matcher(jarFile);
|
||||
String version = "1.0.0";
|
||||
if (matcher.find()) {
|
||||
|
@ -246,8 +259,15 @@ final class NodeLauncherUtil {
|
|||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the packages found in the given JAR to a set.
|
||||
*
|
||||
* @param jarFile
|
||||
* @param packages
|
||||
* @throws IOException
|
||||
*/
|
||||
private static void addPackages(String jarFile, Set<String> packages) throws IOException {
|
||||
String version = ";version=" + version(jarFile);
|
||||
String version = ";version=" + jarVersion(jarFile);
|
||||
ZipInputStream is = new ZipInputStream(new FileInputStream(file(new URL(jarFile))));
|
||||
ZipEntry entry;
|
||||
while ((entry = is.getNextEntry()) != null) {
|
||||
|
@ -264,7 +284,14 @@ final class NodeLauncherUtil {
|
|||
is.close();
|
||||
}
|
||||
|
||||
static Manifest libraryManifest(String[] jarFiles) throws IllegalStateException {
|
||||
/**
|
||||
* Generate a manifest from a list of third-party JAR files.
|
||||
*
|
||||
* @param jarFiles
|
||||
* @return
|
||||
* @throws IllegalStateException
|
||||
*/
|
||||
static private Manifest thirdPartyLibraryBundleManifest(List<String> jarFiles) throws IllegalStateException {
|
||||
try {
|
||||
|
||||
// List exported packages and bundle classpath entries
|
||||
|
@ -313,9 +340,16 @@ final class NodeLauncherUtil {
|
|||
}
|
||||
}
|
||||
|
||||
static InputStream libraryBundle(String[] jarFiles) throws IOException {
|
||||
/**
|
||||
* Generates a library bundle from a list of third-party JARs.
|
||||
*
|
||||
* @param jarFiles
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
static InputStream thirdPartyLibraryBundle(List<String> jarFiles) throws IOException {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
Manifest mf = libraryManifest(jarFiles);
|
||||
Manifest mf = thirdPartyLibraryBundleManifest(jarFiles);
|
||||
JarOutputStream jos = new JarOutputStream(bos, mf);
|
||||
jos.close();
|
||||
return new ByteArrayInputStream(bos.toByteArray());
|
||||
|
@ -327,7 +361,7 @@ final class NodeLauncherUtil {
|
|||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
static String bundleLocation() throws IOException, URISyntaxException {
|
||||
static String thisBundleLocation() throws IOException, URISyntaxException {
|
||||
String resource = NodeLauncherUtil.class.getName().replace('.', '/') + ".class";
|
||||
URL url = NodeLauncherUtil.class.getClassLoader().getResource(resource);
|
||||
if (url == null) {
|
||||
|
@ -348,10 +382,50 @@ final class NodeLauncherUtil {
|
|||
}
|
||||
}
|
||||
|
||||
static Bundle installBundle(BundleContext bundleContext, String location) throws BundleException, IOException {
|
||||
// Development mode, copy the MANIFEST.MF file to the bundle location
|
||||
/**
|
||||
* Returns the location of this bundle.
|
||||
*
|
||||
* @param bundle
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
static String thisBundleLocation(Bundle bundle) throws IOException, URISyntaxException, ClassNotFoundException {
|
||||
String resource = NodeLauncherUtil.class.getName();
|
||||
Class<?> clazz = bundle.loadClass(NodeLauncherUtil.class.getName());
|
||||
URL url = clazz.getProtectionDomain().getCodeSource().getLocation();
|
||||
if (url == null) {
|
||||
throw new FileNotFoundException(resource);
|
||||
}
|
||||
URI uri = url.toURI();
|
||||
|
||||
String scheme = uri.getScheme();
|
||||
if (scheme.equals("jar")) {
|
||||
String path = uri.toString().substring(4);
|
||||
int i = path.indexOf("!/");
|
||||
path = path.substring(0, i);
|
||||
return path;
|
||||
} else {
|
||||
String path = uri.toString();
|
||||
//path = path.substring(0, path.length() - resource.length());
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Install the given bundle.
|
||||
*
|
||||
* @param bundleContext
|
||||
* @param location
|
||||
* @throws BundleException
|
||||
* @throws IOException
|
||||
*/
|
||||
static void fixupBundle(String location) throws BundleException, IOException {
|
||||
File target = file(new URL(location));
|
||||
location = target.toURI().toString();
|
||||
|
||||
// For development mode, copy the MANIFEST.MF file to the bundle location as it's
|
||||
// initially outside of target/classes, at the root of the project.
|
||||
if (location.endsWith("/target/classes/")) {
|
||||
File target = file(new URL(location));
|
||||
File targetManifest = new File(target, "META-INF/MANIFEST.MF");
|
||||
File sourceManifest = new File(target.getParentFile().getParentFile(), "META-INF/MANIFEST.MF");
|
||||
targetManifest.getParentFile().mkdirs();
|
||||
|
@ -368,15 +442,19 @@ final class NodeLauncherUtil {
|
|||
is.close();
|
||||
os.close();
|
||||
}
|
||||
|
||||
Bundle bundle = bundleContext.installBundle(location);
|
||||
return bundle;
|
||||
}
|
||||
|
||||
static String string(Bundle b, boolean verbose) {
|
||||
/**
|
||||
* Returns a string representation of the given bundle.
|
||||
*
|
||||
* @param b
|
||||
* @param verbose
|
||||
* @return
|
||||
*/
|
||||
static String string(Bundle bundle, boolean verbose) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append(b.getBundleId()).append(" ").append(b.getSymbolicName());
|
||||
int s = b.getState();
|
||||
sb.append(bundle.getBundleId()).append(" ").append(bundle.getSymbolicName());
|
||||
int s = bundle.getState();
|
||||
if ((s & Bundle.UNINSTALLED) != 0) {
|
||||
sb.append(" UNINSTALLED");
|
||||
}
|
||||
|
@ -397,9 +475,441 @@ final class NodeLauncherUtil {
|
|||
}
|
||||
|
||||
if (verbose) {
|
||||
sb.append(" ").append(b.getLocation());
|
||||
sb.append(" ").append(b.getHeaders());
|
||||
sb.append(" ").append(bundle.getLocation());
|
||||
sb.append(" ").append(bundle.getHeaders());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of a bundle, or null if the given file is not a bundle.
|
||||
*
|
||||
* @param file
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
static String bundleName(File file) throws IOException {
|
||||
if (!file.exists()) {
|
||||
return null;
|
||||
}
|
||||
String bundleName = null;
|
||||
if (file.isDirectory()) {
|
||||
File mf = new File(file, "META-INF/MANIFEST.MF");
|
||||
if (mf.isFile()) {
|
||||
Manifest manifest = new Manifest(new FileInputStream(mf));
|
||||
bundleName = manifest.getMainAttributes().getValue(BUNDLE_SYMBOLICNAME);
|
||||
} else {
|
||||
if (file.getPath().endsWith("target/classes")) {
|
||||
// Development mode, MANIFEST.MF is outside the bundle location
|
||||
mf = new File(file.getParentFile().getParentFile(), "META-INF/MANIFEST.MF");
|
||||
if (mf.isFile()) {
|
||||
Manifest manifest = new Manifest(new FileInputStream(mf));
|
||||
bundleName = manifest.getMainAttributes().getValue(BUNDLE_SYMBOLICNAME);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
JarFile jar = new JarFile(file, false);
|
||||
Manifest manifest = jar.getManifest();
|
||||
bundleName = manifest.getMainAttributes().getValue(BUNDLE_SYMBOLICNAME);
|
||||
jar.close();
|
||||
}
|
||||
if (bundleName == null) {
|
||||
return bundleName;
|
||||
}
|
||||
int sc = bundleName.indexOf(';');
|
||||
if (sc != -1) {
|
||||
bundleName = bundleName.substring(0, sc);
|
||||
}
|
||||
return bundleName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect JAR files in the given directory.
|
||||
*
|
||||
* @param directory
|
||||
* @param urls
|
||||
* @param filter
|
||||
* @throws MalformedURLException
|
||||
*/
|
||||
private static void collectClasspathEntries(File directory, Set<URL> urls, FilenameFilter filter) throws MalformedURLException {
|
||||
File[] files = directory.listFiles(filter);
|
||||
if (files != null) {
|
||||
int count = 0;
|
||||
for (File file: files) {
|
||||
urls.add(file.toURI().toURL());
|
||||
count++;
|
||||
}
|
||||
if (count != 0) {
|
||||
logger.info("Runtime classpath: "+ count + " JAR" + (count > 1? "s":"")+ " from " + directory.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect development .../ target/classes directories in the given directory.
|
||||
*
|
||||
* @param directory
|
||||
* @param urls
|
||||
* @param filter
|
||||
* @throws MalformedURLException
|
||||
*/
|
||||
private static void collectTargetClassesClasspathEntries(File directory, Set<URL> urls, FilenameFilter filter) throws MalformedURLException {
|
||||
File[] files = directory.listFiles();
|
||||
if (files != null) {
|
||||
int count = 0;
|
||||
for (File file: files) {
|
||||
if (!file.isDirectory()) {
|
||||
continue;
|
||||
}
|
||||
File target = new File(file, "target");
|
||||
if (!target.isDirectory()) {
|
||||
continue;
|
||||
}
|
||||
File classes = new File(target, "classes");
|
||||
if (classes.isDirectory() && filter.accept(target, "classes")) {
|
||||
urls.add(classes.toURI().toURL());
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (count != 0) {
|
||||
logger.info("Runtime classpath: "+ count + " classes folder" + (count > 1? "s":"")+ " from " + directory.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect JAR files under the given distribution directory.
|
||||
*
|
||||
* @param directory
|
||||
* @param jarDirectoryURLs
|
||||
* @param jarURLs
|
||||
* @param filter
|
||||
* @throws MalformedURLException
|
||||
*/
|
||||
private static void collectDistributionClasspathEntries(String directory, Set<URL> jarDirectoryURLs, Set<URL> jarURLs, FilenameFilter filter)
|
||||
throws MalformedURLException {
|
||||
File directoryFile = new File(directory);
|
||||
URL directoryURL = directoryFile.toURI().toURL();
|
||||
if (!jarDirectoryURLs.contains(directoryURL) && directoryFile.exists()) {
|
||||
|
||||
// Collect files under the given directory
|
||||
jarDirectoryURLs.add(directoryURL);
|
||||
collectClasspathEntries(directoryFile, jarURLs, filter);
|
||||
|
||||
// Collect files under <directory>/modules
|
||||
File modulesDirectory = new File(directoryFile, "modules");
|
||||
URL modulesDirectoryURL = modulesDirectory.toURI().toURL();
|
||||
if (!jarDirectoryURLs.contains(modulesDirectoryURL) && modulesDirectory.exists()) {
|
||||
jarDirectoryURLs.add(modulesDirectoryURL);
|
||||
collectClasspathEntries(modulesDirectory, jarURLs, filter);
|
||||
}
|
||||
|
||||
// Collect files under <directory>/lib
|
||||
File libDirectory = new File(directoryFile, "lib");
|
||||
URL libDirectoryURL = libDirectory.toURI().toURL();
|
||||
if (!jarDirectoryURLs.contains(libDirectoryURL) && libDirectory.exists()) {
|
||||
jarDirectoryURLs.add(libDirectoryURL);
|
||||
collectClasspathEntries(libDirectory, jarURLs, filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the Tuscany runtime classpath entries.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
static Set<URL> runtimeClasspathEntries() throws FileNotFoundException,
|
||||
URISyntaxException, MalformedURLException {
|
||||
|
||||
// Build list of runtime JARs
|
||||
Set<URL> jarDirectoryURLs = new HashSet<URL>();
|
||||
Set<URL> jarURLs = new HashSet<URL>();
|
||||
|
||||
// Determine the path to the launcher class
|
||||
URI uri = URI.create(codeLocation(NodeLauncherUtil.class));
|
||||
|
||||
// If the launcher class is in a JAR, add all runtime JARs from directory containing
|
||||
// that JAR (e.g. the Tuscany modules directory) as well as the ../modules and
|
||||
// ../lib directories
|
||||
if (uri.getPath().endsWith(".jar")) {
|
||||
|
||||
File file = new File(uri);
|
||||
if (file.exists()) {
|
||||
File jarDirectory = file.getParentFile();
|
||||
if (jarDirectory != null && jarDirectory.exists()) {
|
||||
|
||||
// Collect JAR files from the directory containing the input JAR
|
||||
// (e.g. the Tuscany modules directory)
|
||||
URL jarDirectoryURL = jarDirectory.toURI().toURL();
|
||||
jarDirectoryURLs.add(jarDirectoryURL);
|
||||
collectClasspathEntries(jarDirectory, jarURLs, new StandAloneJARFileNameFilter());
|
||||
|
||||
File homeDirectory = jarDirectory.getParentFile();
|
||||
if (homeDirectory != null && homeDirectory.exists()) {
|
||||
collectDistributionClasspathEntries(homeDirectory.getAbsolutePath(), jarDirectoryURLs, jarURLs, new StandAloneJARFileNameFilter());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (uri.getPath().endsWith("target/classes/")) {
|
||||
|
||||
// Development mode, we're running off classes in a workspace
|
||||
// and not from Maven surefire, collect all bundles in the workspace
|
||||
ClassLoader cl = NodeLauncherUtil.class.getClassLoader();
|
||||
if (!cl.getClass().getName().startsWith("org.apache.maven.surefire")) {
|
||||
File file = new File(uri);
|
||||
if (file.exists()) {
|
||||
File moduleDirectory = file.getParentFile().getParentFile();
|
||||
if (moduleDirectory != null) {
|
||||
File modulesDirectory = moduleDirectory.getParentFile();
|
||||
if (modulesDirectory != null && modulesDirectory.exists() && modulesDirectory.getName().equals("modules")) {
|
||||
collectDevelopmentClasspathEntries(modulesDirectory.getAbsolutePath(), jarDirectoryURLs, jarURLs, new StandAloneDevelopmentClassesFileNameFilter());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Look for a TUSCANY_HOME system property or environment variable
|
||||
// Add all the JARs found under $TUSCANY_HOME, $TUSCANY_HOME/modules
|
||||
// and $TUSCANY_HOME/lib
|
||||
String home = getProperty(TUSCANY_HOME);
|
||||
if (home != null && home.length() != 0) {
|
||||
logger.info(TUSCANY_HOME + ": " + home);
|
||||
collectDistributionClasspathEntries(home, jarDirectoryURLs, jarURLs, new StandAloneJARFileNameFilter());
|
||||
}
|
||||
|
||||
// Look for a TUSCANY_PATH system property or environment variable
|
||||
// Add all the JARs found under $TUSCANY_PATH, $TUSCANY_PATH/modules
|
||||
// and $TUSCANY_PATH/lib
|
||||
String ext = getProperty(TUSCANY_PATH);
|
||||
if (ext != null && ext.length() != 0) {
|
||||
logger.info(TUSCANY_PATH + ": " + ext);
|
||||
String separator = getProperty("path.separator");
|
||||
for (StringTokenizer tokens = new StringTokenizer(ext, separator); tokens.hasMoreTokens();) {
|
||||
collectDistributionClasspathEntries(tokens.nextToken(), jarDirectoryURLs, jarURLs, new StandAloneJARFileNameFilter());
|
||||
}
|
||||
}
|
||||
|
||||
// Add the classpath entries from the current classloader
|
||||
collectClassLoaderClasspathEntries(jarURLs, NodeLauncherUtil.class.getClassLoader(), false);
|
||||
|
||||
return jarURLs;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the JAR files on the classpath used by the given classloader.
|
||||
*
|
||||
* @param classLoader
|
||||
* @return
|
||||
*/
|
||||
static List<URL> jarFilesOnClasspath(ClassLoader classLoader) {
|
||||
Set<URL> entries = new HashSet<URL>();
|
||||
collectClassLoaderClasspathEntries(entries, classLoader, false);
|
||||
return new ArrayList<URL>(entries);
|
||||
}
|
||||
|
||||
private static String getProperty(final String prop) {
|
||||
return AccessController.doPrivileged(new PrivilegedAction<String>() {
|
||||
public String run() {
|
||||
String value = System.getProperty(prop);
|
||||
if (value == null || value.length() == 0) {
|
||||
return System.getenv(prop);
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect JARs on the classpath of a URLClassLoader.
|
||||
*
|
||||
* @param urls
|
||||
* @param cl
|
||||
*/
|
||||
private static void collectClassLoaderClasspathEntries(Set<URL> urls, ClassLoader cl, boolean recursive) {
|
||||
if (cl == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Collect JARs from the URLClassLoader's classpath
|
||||
if (cl instanceof URLClassLoader) {
|
||||
URL[] jarURLs = ((URLClassLoader)cl).getURLs();
|
||||
if (jarURLs != null) {
|
||||
for (URL jarURL : jarURLs) {
|
||||
urls.add(jarURL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Collect JARs from the parent ClassLoader
|
||||
if (recursive) {
|
||||
collectClassLoaderClasspathEntries(urls, cl.getParent(), recursive);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A file name filter used to filter JAR files.
|
||||
*/
|
||||
private static class StandAloneJARFileNameFilter implements FilenameFilter {
|
||||
|
||||
public boolean accept(File dir, String name) {
|
||||
name = name.toLowerCase();
|
||||
|
||||
// Filter out the Tomcat and Webapp hosts
|
||||
if (name.startsWith("tuscany-host-tomcat") ||
|
||||
name.startsWith("tuscany-host-webapp")) {
|
||||
//FIXME This is temporary
|
||||
return false;
|
||||
}
|
||||
|
||||
// Include JAR and MAR files
|
||||
if (name.endsWith(".jar")) {
|
||||
return true;
|
||||
}
|
||||
if (name.endsWith(".mar")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A file name filter used to filter target/classes directories.
|
||||
*/
|
||||
private static class StandAloneDevelopmentClassesFileNameFilter implements FilenameFilter {
|
||||
|
||||
public boolean accept(File dir, String name) {
|
||||
name = name.toLowerCase();
|
||||
if (dir.getName().equals("target") && name.equals("classes")) {
|
||||
|
||||
// Filter out the Tomcat and Webapp hosts
|
||||
String dirPath = dir.getAbsolutePath();
|
||||
if (dirPath.endsWith("host-tomcat/target") ||
|
||||
dirPath.endsWith("host-webapp/target")) {
|
||||
//FIXME This is temporary
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Filter out the Tomcat and Webapp hosts
|
||||
if (name.startsWith("tuscany-host-tomcat") ||
|
||||
name.startsWith("tuscany-host-webapp")) {
|
||||
//FIXME This is temporary
|
||||
return false;
|
||||
}
|
||||
|
||||
// Include JAR and MAR files
|
||||
if (name.endsWith(".jar")) {
|
||||
return true;
|
||||
}
|
||||
if (name.endsWith(".mar")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A file name filter used to filter JAR files.
|
||||
*/
|
||||
private static class WebAppJARFileNameFilter extends StandAloneJARFileNameFilter {
|
||||
|
||||
@Override
|
||||
public boolean accept(File dir, String name) {
|
||||
if (!super.accept(dir, name)) {
|
||||
return false;
|
||||
}
|
||||
name = name.toLowerCase();
|
||||
|
||||
// Exclude servlet-api JARs
|
||||
if (name.startsWith("servlet-api")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Exclude the Tomcat and Jetty hosts
|
||||
if (name.startsWith("tuscany-host-tomcat") || name.startsWith("tuscany-host-jetty")) {
|
||||
//FIXME This is temporary
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the File object representing the given URL.
|
||||
*
|
||||
* @param url
|
||||
* @return
|
||||
*/
|
||||
static File file(URL url) {
|
||||
if (url == null || !url.getProtocol().equals("file")) {
|
||||
return null;
|
||||
} else {
|
||||
String filename = url.getFile().replace('/', File.separatorChar);
|
||||
int pos = 0;
|
||||
while ((pos = filename.indexOf('%', pos)) >= 0) {
|
||||
if (pos + 2 < filename.length()) {
|
||||
String hexStr = filename.substring(pos + 1, pos + 3);
|
||||
char ch = (char)Integer.parseInt(hexStr, 16);
|
||||
filename = filename.substring(0, pos) + ch + filename.substring(pos + 3);
|
||||
}
|
||||
}
|
||||
return new File(filename);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the location of the classpath entry, JAR, WAR etc. containing the given class.
|
||||
*
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
static private String codeLocation(Class<?> clazz) {
|
||||
String filename = clazz.getProtectionDomain().getCodeSource().getLocation().toString();
|
||||
int pos = 0;
|
||||
while ((pos = filename.indexOf('%', pos)) >= 0) {
|
||||
if (pos + 2 < filename.length()) {
|
||||
String hexStr = filename.substring(pos + 1, pos + 3);
|
||||
char ch = (char)Integer.parseInt(hexStr, 16);
|
||||
filename = filename.substring(0, pos) + ch + filename.substring(pos + 3);
|
||||
}
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect JAR files under the given distribution directory.
|
||||
*
|
||||
* @param directory
|
||||
* @param jarDirectoryURLs
|
||||
* @param jarURLs
|
||||
* @param filter
|
||||
* @throws MalformedURLException
|
||||
*/
|
||||
private static void collectDevelopmentClasspathEntries(String directory, Set<URL> jarDirectoryURLs, Set<URL> jarURLs, FilenameFilter filter)
|
||||
throws MalformedURLException {
|
||||
File directoryFile = new File(directory);
|
||||
URL directoryURL = directoryFile.toURI().toURL();
|
||||
if (!jarDirectoryURLs.contains(directoryURL) && directoryFile.exists()) {
|
||||
|
||||
// Collect files under the given directory
|
||||
jarDirectoryURLs.add(directoryURL);
|
||||
collectTargetClassesClasspathEntries(directoryFile, jarURLs, filter);
|
||||
|
||||
// Collect files under <directory>/thirdparty-library/lib
|
||||
File libDirectory = new File(directoryFile, "thirdparty-library/lib");
|
||||
URL libDirectoryURL = libDirectory.toURI().toURL();
|
||||
if (!jarDirectoryURLs.contains(libDirectoryURL) && libDirectory.exists()) {
|
||||
jarDirectoryURLs.add(libDirectoryURL);
|
||||
collectClasspathEntries(libDirectory, jarURLs, filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.osgi.framework.BundleContext;
|
|||
*
|
||||
*/
|
||||
public class EquinoxOSGiHostTestCase {
|
||||
|
||||
@Test
|
||||
public void testStartThenStop() {
|
||||
EquinoxHost host = new EquinoxHost();
|
||||
|
@ -45,17 +46,22 @@ public class EquinoxOSGiHostTestCase {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testStartTwice() {
|
||||
public void testStartThenStopTwice() {
|
||||
EquinoxHost host = new EquinoxHost();
|
||||
host.start();
|
||||
try {
|
||||
host.start();
|
||||
Assert.fail();
|
||||
} catch (IllegalStateException e) {
|
||||
Assert.assertTrue(IllegalStateException.class.isInstance(e.getCause()));
|
||||
} finally {
|
||||
host.stop();
|
||||
BundleContext context = host.start();
|
||||
Assert.assertNotNull(context);
|
||||
for (Bundle b : context.getBundles()) {
|
||||
System.out.println(toString(b, false));
|
||||
}
|
||||
host.stop();
|
||||
|
||||
host = new EquinoxHost();
|
||||
context = host.start();
|
||||
Assert.assertNotNull(context);
|
||||
for (Bundle b : context.getBundles()) {
|
||||
System.out.println(toString(b, false));
|
||||
}
|
||||
host.stop();
|
||||
}
|
||||
|
||||
public static String toString(Bundle b, boolean verbose) {
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Apache Tuscany SCA Calculator RCP Sample
|
||||
Bundle-SymbolicName: sample.calculator.rcp;singleton:=true
|
||||
Bundle-Version: 1.4.0.SNAPSHOT
|
||||
Bundle-Activator: calculator.rcp.Activator
|
||||
Bundle-Vendor: The Apache Software Foundation
|
||||
Require-Bundle: org.eclipse.ui,
|
||||
org.eclipse.core.runtime
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Import-Package: org.apache.tuscany.sca.extensibility.equinox;version="1.4.0",
|
||||
org.apache.tuscany.sca.node;version="1.4.0",
|
||||
org.osoa.sca;version="1.4.0",
|
||||
org.osoa.sca.annotations;version="1.4.0"
|
||||
Bundle-ClassPath: .,
|
||||
cglib-nodep-2.1_3.jar,
|
||||
jaxb-impl-2.1.7.jar,
|
||||
activation-1.1.jar,
|
||||
jsr250-api-1.0.jar,
|
||||
jsr181-api-1.0-MR1.jar,
|
||||
jaxb-api-2.1.jar,
|
||||
stax-api-1.0-2.jar,
|
||||
jaxws-api-2.1.jar,
|
||||
geronimo-commonj_1.1_spec-1.0.jar,
|
||||
XmlSchema-1.3.2.jar,
|
||||
wstx-asl-3.2.1.jar
|
|
@ -0,0 +1 @@
|
|||
This directory contains a generated MANIFEST.MF file.
|
|
@ -41,30 +41,35 @@
|
|||
<artifactId>tuscany-node-api</artifactId>
|
||||
<version>1.4-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.tuscany.sca</groupId>
|
||||
<artifactId>tuscany-node-impl</artifactId>
|
||||
<version>1.4-SNAPSHOT</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.tuscany.sca</groupId>
|
||||
<artifactId>tuscany-implementation-java-runtime</artifactId>
|
||||
<version>1.4-SNAPSHOT</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.tuscany.sca</groupId>
|
||||
<artifactId>tuscany-implementation-node-runtime</artifactId>
|
||||
<version>1.4-SNAPSHOT</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.tuscany.sca</groupId>
|
||||
<artifactId>tuscany-extensibility-equinox</artifactId>
|
||||
<version>1.4-SNAPSHOT</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.tuscany.sca</groupId>
|
||||
<artifactId>tuscany-node-launcher-equinox</artifactId>
|
||||
|
@ -173,6 +178,34 @@
|
|||
</classpathContainers>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<version>1.4.3</version>
|
||||
<extensions>true</extensions>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>bundle-manifest</id>
|
||||
<phase>process-classes</phase>
|
||||
<goals>
|
||||
<goal>manifest</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Bundle-Version>1.4</Bundle-Version>
|
||||
<Bundle-SymbolicName>sample.calculator.rcp;singleton:=true</Bundle-SymbolicName>
|
||||
<Bundle-Description>${pom.name}</Bundle-Description>
|
||||
<Bundle-Activator>calculator.rcp.Activator</Bundle-Activator>
|
||||
<Eclipse-LazyStart>true</Eclipse-LazyStart>
|
||||
<Export-Package>calculator.rcp*</Export-Package>
|
||||
</instructions>
|
||||
<manifestLocation>${basedir}/META-INF</manifestLocation>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
|
|
|
@ -20,7 +20,6 @@ package calculator.rcp;
|
|||
|
||||
import java.io.File;
|
||||
|
||||
import org.apache.tuscany.sca.extensibility.equinox.EquinoxServiceDiscoverer;
|
||||
import org.apache.tuscany.sca.node.SCANode;
|
||||
import org.apache.tuscany.sca.node.equinox.launcher.Contribution;
|
||||
import org.apache.tuscany.sca.node.equinox.launcher.NodeLauncher;
|
||||
|
@ -42,28 +41,18 @@ public class Activator extends AbstractUIPlugin {
|
|||
private NodeLauncher launcher;
|
||||
private SCANode node;
|
||||
|
||||
/**
|
||||
* The constructor
|
||||
*/
|
||||
public Activator() {
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
|
||||
*/
|
||||
public void start(BundleContext context) throws Exception {
|
||||
super.start(context);
|
||||
plugin = this;
|
||||
|
||||
launcher = NodeLauncher.newInstance();
|
||||
node = launcher.createNode("Calculator.composite", new Contribution("c1", new File("target/classes").toURI().toString()));
|
||||
node.start();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
|
||||
*/
|
||||
public void stop(BundleContext context) throws Exception {
|
||||
plugin = null;
|
||||
super.stop(context);
|
||||
|
|
|
@ -29,9 +29,6 @@ import org.eclipse.ui.PlatformUI;
|
|||
*/
|
||||
public class Application implements IApplication {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.equinox.app.IApplication#start(org.eclipse.equinox.app.IApplicationContext)
|
||||
*/
|
||||
public Object start(IApplicationContext context) {
|
||||
Display display = PlatformUI.createDisplay();
|
||||
try {
|
||||
|
@ -45,9 +42,6 @@ public class Application implements IApplication {
|
|||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.equinox.app.IApplication#stop()
|
||||
*/
|
||||
public void stop() {
|
||||
final IWorkbench workbench = PlatformUI.getWorkbench();
|
||||
if (workbench == null)
|
||||
|
|
Loading…
Add table
Reference in a new issue