diff options
author | jsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68> | 2008-09-07 11:25:41 +0000 |
---|---|---|
committer | jsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68> | 2008-09-07 11:25:41 +0000 |
commit | 749d5c9a1c6a58fb7ff9078d97afb96039f89b7a (patch) | |
tree | 8057292ef3e9d14636a225811090b74f9faab2e8 /java/sca/modules/node-launcher-equinox/src/main | |
parent | 252f4d6eecc3cb008a9b8c139bdafdf588ecadc8 (diff) |
Moved hooks from extensiblity-equinox to node-launcher-equinox. Fixed logic that installs bundles in node-launcher-equinox, which now just installs bundles normally and installs all non-bundle JARs in a single 'library' bundle which exports all the packages that they contain. The startup sequence is now simpler and significantly faster.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@692820 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'java/sca/modules/node-launcher-equinox/src/main')
12 files changed, 641 insertions, 781 deletions
diff --git a/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/DomainManagerLauncher.java b/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/DomainManagerLauncher.java index c9ee58a2a6..61187eecac 100644 --- a/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/DomainManagerLauncher.java +++ b/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/DomainManagerLauncher.java @@ -77,13 +77,13 @@ public class DomainManagerLauncher { // Create a launcher DomainManagerLauncher launcher = newInstance(); - EquinoxOSGiHost equinox = null; + EquinoxHost equinox = null; Object domainManager = null; ShutdownThread shutdown = null; try { // Start the OSGi host - equinox = new EquinoxOSGiHost(); + equinox = new EquinoxHost(); equinox.start(); // Start the domain manager @@ -148,9 +148,9 @@ public class DomainManagerLauncher { private static class ShutdownThread extends Thread { private Object domainManager; - private EquinoxOSGiHost equinox; + private EquinoxHost equinox; - public ShutdownThread(Object domainManager, EquinoxOSGiHost equinox) { + public ShutdownThread(Object domainManager, EquinoxHost equinox) { super(); this.domainManager = domainManager; this.equinox = equinox; diff --git a/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/EquinoxHookConfigurator.java b/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/EquinoxHookConfigurator.java new file mode 100644 index 0000000000..fed763096a --- /dev/null +++ b/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/EquinoxHookConfigurator.java @@ -0,0 +1,58 @@ +/* + * 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 java.util.jar.Manifest; +import java.util.logging.Logger; + +import org.eclipse.osgi.baseadaptor.HookConfigurator; +import org.eclipse.osgi.baseadaptor.HookRegistry; + +/** + * Hook Configurator for Equinox. + * + * @version $Rev: $ $Date: $ + */ +public class EquinoxHookConfigurator implements HookConfigurator { + private static Logger logger = Logger.getLogger(HookConfigurator.class.getName()); + + private String[] jarFiles; + private Manifest manifest; + + public EquinoxHookConfigurator() { + + // Get the list of JAR files to install + String jarFilesProperty = System.getProperty("org.apache.tuscany.sca.node.launcher.equinox.jarFiles"); + jarFiles = jarFilesProperty.split(";"); + + // Create a single 'library' bundle for them + long libraryStart = System.currentTimeMillis(); + manifest = NodeLauncherUtil.libraryManifest(jarFiles); + logger.info("Third-party library manifest generated in " + (System.currentTimeMillis() - libraryStart) + " ms"); + + } + + public void addHooks(HookRegistry registry) { + + // Register our BundleFileFactory hook + registry.addBundleFileFactoryHook(new LibrariesBundleFileFactoryHook(manifest)); + } + +} diff --git a/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/EquinoxHost.java b/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/EquinoxHost.java new file mode 100644 index 0000000000..b60032b5b9 --- /dev/null +++ b/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/EquinoxHost.java @@ -0,0 +1,214 @@ +/* + * 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.string; +import static org.osgi.framework.Constants.BUNDLE_SYMBOLICNAME; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.net.URL; +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.logging.Logger; + +import org.eclipse.core.runtime.adaptor.EclipseStarter; +import org.eclipse.core.runtime.adaptor.LocationManager; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; + +/** + * Wraps the Equinox runtime. + */ +public class EquinoxHost { + private static Logger logger = Logger.getLogger(EquinoxHost.class.getName()); + + private BundleContext context; + + private final static String systemPackages = + "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, " + + "javax.xml, " + + "javax.xml.datatype, " + + "javax.xml.namespace, " + + "javax.xml.parsers, " + + "javax.xml.transform, " + + "javax.xml.transform.dom, " + + "javax.xml.transform.sax, " + + "javax.xml.transform.stream, " + + "javax.xml.validation, " + + "javax.xml.xpath, " + // Force the classes to be imported from the system bundle + // + "javax.xml.stream, " + // + "javax.xml.stream.util, " + + "javax.sql," + + "org.w3c.dom, " + + "org.xml.sax, " + + "org.xml.sax.ext, " + + "org.xml.sax.helpers, " + + "javax.security.auth, " + + "javax.security.cert, " + + "javax.security.auth.login, " + + "javax.security.auth.callback, " + + "javax.naming, " + + "javax.naming.spi, " + + "javax.naming.directory, " + + "javax.management, " + + "javax.imageio, " + + "sun.misc, " + + "javax.net, " + + "javax.net.ssl, " + + "javax.crypto, " + + "javax.rmi, " + + "javax.transaction, " + + "javax.transaction.xa"; + + 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); + + // Set the extension bundle + props.put("osgi.framework.extensions", "org.apache.tuscany.sca.extensibility.equinox"); + + // Set startup properties + props.put(EclipseStarter.PROP_CLEAN, "true"); + + // 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()); + } else { + urls = JarFileFinder.getClassPathEntries(JarFileFinder.class.getClassLoader(), false); + } + + // 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); + if (bundleName != null) { + bundleFiles.append(url.toString() + ";"); + bundleNames.append(bundleName + ";"); + } else { + if (file.isFile()) { + jarFiles.append(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 + context = EclipseStarter.startup(new String[]{}, null); + + // FIXME use the correct bundle location + Bundle launcherBundle = context.installBundle(new File("target/classes").toURI().toURL().toString()); + logger.info("Starting bundle: " + string(launcherBundle, false)); + launcherBundle.start(); + + // Start all bundles for now to help diagnose any class loading issues + //for (Bundle bundle: context.getBundles()) { + // if ((bundle.getState() & Bundle.ACTIVE) == 0) { + // logger.info("Starting bundle: " + string(bundle, false)); + // bundle.start(); + // } + //} + + return context; + + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + + public void stop() { + try { + 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 { + 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 { + 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; + } + +} diff --git a/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/EquinoxOSGiHost.java b/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/EquinoxOSGiHost.java deleted file mode 100644 index bacfc4df87..0000000000 --- a/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/EquinoxOSGiHost.java +++ /dev/null @@ -1,178 +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 java.io.File; -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.Map; - -import org.eclipse.core.runtime.adaptor.EclipseStarter; -import org.eclipse.core.runtime.adaptor.LocationManager; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.osgi.framework.Constants; - -/** - * Wraps the Equinox runtime. - */ -public class EquinoxOSGiHost { - private LauncherBundleActivator activator = new LauncherBundleActivator(); - private BundleContext context; - private ClassLoader tccl; - - private final static String systemPackages = - "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, " - + "javax.xml, " - + "javax.xml.datatype, " - + "javax.xml.namespace, " - + "javax.xml.parsers, " - + "javax.xml.transform, " - + "javax.xml.transform.dom, " - + "javax.xml.transform.sax, " - + "javax.xml.transform.stream, " - + "javax.xml.validation, " - + "javax.xml.xpath, " - // Force the classes to be imported from the system bundle - // + "javax.xml.stream, " - // + "javax.xml.stream.util, " - + "javax.sql," - + "org.w3c.dom, " - + "org.xml.sax, " - + "org.xml.sax.ext, " - + "org.xml.sax.helpers, " - + "javax.security.auth, " - + "javax.security.cert, " - + "javax.security.auth.login, " - + "javax.security.auth.callback, " - + "javax.naming, " - + "javax.naming.spi, " - + "javax.naming.directory, " - + "javax.management, " - + "javax.imageio, " - + "sun.misc, " - + "javax.net, " - + "javax.net.ssl, " - + "javax.crypto, " - + "javax.rmi, " - + "javax.transaction, " - + "javax.transaction.xa"; - - public BundleContext start() { - try { - return startup(); - } catch (Exception e) { - throw new IllegalStateException(e); - } - } - - public Bundle findBundle(String symbolicName, String version) { - if (context == null) { - return null; - } - Bundle[] bundles = context.getBundles(); - if (version == null) { - version = "0.0.0"; - } - for (Bundle b : bundles) { - String v = (String)b.getHeaders().get(Constants.BUNDLE_VERSION); - if (v == null) { - v = "0.0.0"; - } - if (b.getSymbolicName().equals(symbolicName) && (version.equals("0.0.0") || v.equals(version))) { - return b; - } - } - return null; - } - - public void stop() { - try { - shutdown(); - } catch (Exception e) { - throw new IllegalStateException(e); - } - } - - public BundleContext getBundleContext() { - return context; - } - - private BundleContext startup() throws Exception { - String args[] = {}; - Map<Object, Object> props = new HashMap<Object, Object>(); - props.put("org.osgi.framework.system.packages", systemPackages); - // Set the extension bundle - props.put("osgi.framework.extensions", "org.apache.tuscany.sca.extensibility.equinox"); - props.put(EclipseStarter.PROP_CLEAN, "true"); - 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); - context = EclipseStarter.startup(args, null); - activator.start(context); - -// [rfeng] This is useful to report bundle resolving issues -// for (Bundle b : context.getBundles()) { -// System.out.println("Starting: " + b); -// try { -// b.start(); -// } catch (BundleException e) { -// e.printStackTrace(); -// } -// } - tccl = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(getContextClassLoader()); - return context; - } - - private ClassLoader getContextClassLoader() { - Bundle b = findBundle("org.apache.tuscany.sca.extensibility.equinox", null); - if (b != null) { - try { - b.start(); - Class<?> discovererClass = b.loadClass("org.apache.tuscany.sca.extensibility.ServiceDiscovery"); - Method getInstance = discovererClass.getMethod("getInstance"); - Object instance = getInstance.invoke(null); - Method getter = discovererClass.getMethod("getServiceDiscoverer"); - Object discoverer = getter.invoke(instance); - - Method getCL = discoverer.getClass().getMethod("getContextClassLoader"); - ClassLoader cl = (ClassLoader)getCL.invoke(discoverer); - return cl; - } catch (Exception e) { - throw new IllegalStateException(e); - } - } - throw new IllegalStateException("Bundle org.apache.tuscany.sca.extensibility.equinox is not installed"); - } - - private void shutdown() throws Exception { - activator.stop(context); - EclipseStarter.shutdown(); - Thread.currentThread().setContextClassLoader(tccl); - } - -} diff --git a/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/JarFileFinder.java b/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/JarFileFinder.java index eb7edd36b9..476c65958e 100644 --- a/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/JarFileFinder.java +++ b/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/JarFileFinder.java @@ -19,6 +19,8 @@ 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; @@ -324,23 +326,6 @@ public class JarFileFinder { }); } - public static File toFile(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 URL getContainer(URL resourceURL, String resourceName) { URL root = null; // "jar:file://....../something.jar!/a/b/c/app.composite" @@ -358,7 +343,7 @@ public class JarFileFinder { try { root = AccessController.doPrivileged(new PrivilegedExceptionAction<URL>() { public URL run() throws IOException { - return toFile(new URL(location)).toURI().toURL(); + return file(new URL(location)).toURI().toURL(); } }); } catch (PrivilegedActionException e) { @@ -370,14 +355,14 @@ public class JarFileFinder { // jar contribution String location = url.substring(4, url.lastIndexOf("!/")); // workaround for evil URL/URI from Maven - root = toFile(new URL(location)).toURI().toURL(); + 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 = toFile(new URL(location)).toURI().toURL(); + 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(), "/"); diff --git a/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/LauncherBundleActivator.java b/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/LauncherBundleActivator.java index 3f259c33a7..0c71970b95 100644 --- a/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/LauncherBundleActivator.java +++ b/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/LauncherBundleActivator.java @@ -1,26 +1,12 @@ package org.apache.tuscany.sca.node.equinox.launcher; import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.URL; import java.util.ArrayList; import java.util.HashSet; import java.util.List; -import java.util.jar.Attributes; -import java.util.jar.JarEntry; -import java.util.jar.JarInputStream; -import java.util.jar.JarOutputStream; -import java.util.jar.Manifest; +import java.util.Set; 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; import org.osgi.framework.Bundle; import org.osgi.framework.BundleActivator; @@ -30,465 +16,90 @@ import org.osgi.framework.BundleListener; import org.osgi.framework.Constants; /** - * Bundle activator which installs Tuscany modules and 3rd party jars into an OSGi runtime. + * Bundle activator which installs Tuscany modules into an OSGi runtime. * */ public class LauncherBundleActivator implements BundleActivator, Constants, BundleListener { private static Logger logger = Logger.getLogger(LauncherBundleActivator.class.getName()); - private static final String[] immutableJars = {"bcprov"}; + private List<Bundle> installedBundles = new ArrayList<Bundle>(); private BundleContext bundleContext; - private List<Bundle> tuscanyBundles = new ArrayList<Bundle>(); - - private List<URL> jarFiles; public LauncherBundleActivator() { super(); } - public LauncherBundleActivator(List<URL> jarFiles) { - super(); - this.jarFiles = jarFiles; - } - - public static String toString(Bundle b, boolean verbose) { - StringBuffer sb = new StringBuffer(); - sb.append(b.getBundleId()).append(" ").append(b.getSymbolicName()); - int s = b.getState(); - if ((s & Bundle.UNINSTALLED) != 0) { - sb.append(" UNINSTALLED"); - } - if ((s & Bundle.INSTALLED) != 0) { - sb.append(" INSTALLED"); - } - if ((s & Bundle.RESOLVED) != 0) { - sb.append(" RESOLVED"); - } - if ((s & Bundle.STARTING) != 0) { - sb.append(" STARTING"); - } - if ((s & Bundle.STOPPING) != 0) { - sb.append(" STOPPING"); - } - if ((s & Bundle.ACTIVE) != 0) { - sb.append(" ACTIVE"); - } - - if (verbose) { - sb.append(" ").append(b.getLocation()); - sb.append(" ").append(b.getHeaders()); - } - return sb.toString(); - } - public void start(BundleContext bundleContext) throws Exception { this.bundleContext = bundleContext; this.bundleContext.addBundleListener(this); - installTuscany(bundleContext); - for (Bundle b : bundleContext.getBundles()) { - try { - if ("org.apache.tuscany.sca.contribution.osgi".equals(b.getSymbolicName()) || "org.apache.tuscany.sca.extensibility.equinox" - .equals(b.getSymbolicName())) { - if (b.getHeaders().get("Fragment-Host") == null) { - b.start(); - logger.info(toString(b, false) + " " + b.getState()); - } + // Install the Tuscany bundles + long start = System.currentTimeMillis(); + + // FIXME: SDO bundles dont have the correct dependencies + System.setProperty("commonj.sdo.impl.HelperProvider", "org.apache.tuscany.sdo.helper.HelperProviderImpl"); + + // Get the list of JAR files to install + String jarFilesProperty = System.getProperty("org.apache.tuscany.sca.node.launcher.equinox.jarFiles"); + String[] jarFiles = jarFilesProperty.split(";"); + + // Create a single 'library' bundle for them + long libraryStart = System.currentTimeMillis(); + //InputStream library = NodeLauncherUtil.libraryBundle(jarFiles); + Bundle libraryBundle = bundleContext.installBundle("org.apache.tuscany.sca.node.launcher.equinox.libraries", new ByteArrayInputStream(new byte[0])); + installedBundles.add(libraryBundle); + logger.info("Third-party library bundle installed in " + (System.currentTimeMillis() - libraryStart) + " ms: " + NodeLauncherUtil.string(libraryBundle, false)); + + // 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 = System.getProperty("org.apache.tuscany.sca.node.launcher.equinox.bundleFiles"); + String[] bundleFiles = bundleFilesProperty.split(";"); + String bundleNamesProperty = System.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; } - } catch (Exception e) { - logger.log(Level.SEVERE, e.getMessage(), e); + long installStart = System.currentTimeMillis(); + Bundle bundle = bundleContext.installBundle(bundleFile); + //logger.info("Bundle installed in " + (System.currentTimeMillis() - installStart) + " ms: " + NodeLauncherUtil.string(bundle, false)); + installedBundles.add(bundle); } } + + long end = System.currentTimeMillis(); + logger.info("Tuscany bundles are installed in " + (end - start) + " ms."); } public void stop(BundleContext bundleContext) throws Exception { - /* - for (Bundle bundle : tuscanyBundles) { - try { - bundle.stop(); - } catch (Exception e) { - logger.log(Level.SEVERE, e.getMessage(), e); - } - } - */ - - for (Bundle bundle : tuscanyBundles) { + + // Uninstall all the bundles we've installed + for (Bundle bundle : installedBundles) { try { - if (logger.isLoggable(Level.FINE)) { - logger.fine("Uninstalling bundle: " + toString(bundle, false)); - } + //if (logger.isLoggable(Level.FINE)) { + // logger.info("Uninstalling bundle: " + NodeLauncherUtil.string(bundle, false)); + //} bundle.uninstall(); } catch (Exception e) { logger.log(Level.SEVERE, e.getMessage(), e); } } + installedBundles.clear(); + this.bundleContext.removeBundleListener(this); - tuscanyBundles.clear(); this.bundleContext = null; } - public void installTuscany(BundleContext bundleContext) { - long start = System.currentTimeMillis(); - - try { - - // FIXME: SDO bundles dont have the correct dependencies - System.setProperty("commonj.sdo.impl.HelperProvider", "org.apache.tuscany.sdo.helper.HelperProviderImpl"); - List<URL> urls = jarFiles; - if (urls == null) { - File tuscanyInstallDir = findTuscanyInstallDir(bundleContext.getBundle()); - - if (tuscanyInstallDir != null) { - urls = - JarFileFinder.findJarFiles(tuscanyInstallDir, new JarFileFinder.StandAloneJARFileNameFilter()); - } else { - urls = JarFileFinder.getClassPathEntries(JarFileFinder.class.getClassLoader(), false); - } - } - - for (URL url : urls) { - File file = new File(url.toURI()); - if (file.getName().startsWith("org.apache.felix.") || file.getName().startsWith("osgi-") - || file.getName().startsWith("org.osgi.")) { - continue; - } - try { - Bundle bundle = createAndInstallBundle(bundleContext, url); - } catch (Exception e) { - logger.log(Level.SEVERE, e.getMessage(), e); - } - } - - long end = System.currentTimeMillis(); - logger.info("Tuscany bundles are installed in " + (end - start) + " ms."); - - } catch (Exception e) { - e.printStackTrace(); - } - } - - private File findTuscanyInstallDir(Bundle bundle) throws IOException { - String tuscanyDirName = JarFileFinder.getProperty(JarFileFinder.TUSCANY_HOME); - if (tuscanyDirName != null) { - File tuscanyInstallDir = new File(tuscanyDirName); - if (tuscanyInstallDir.exists() && tuscanyInstallDir.isDirectory()) - return tuscanyInstallDir; - } - - /* - String location = bundle.getLocation(); - - if (location != null && location.startsWith("file:")) { - File file = new File(URI.create(location)); - File tuscanyInstallDir = file.getParentFile(); - if (tuscanyInstallDir.exists() && tuscanyInstallDir.isDirectory()) - return tuscanyInstallDir; - } - if (this.getClass().getProtectionDomain() != null) { - CodeSource codeSource = this.getClass().getProtectionDomain().getCodeSource(); - if (codeSource != null) { - try { - File tuscanyInstallDir = new File(codeSource.getLocation().toURI()); - if (tuscanyInstallDir.exists() && tuscanyInstallDir.isDirectory()) - return tuscanyInstallDir; - } catch (Exception e) { - // ignore - } - } - } - */ - return null; - } - - public Bundle createAndInstallBundle(BundleContext bundleContext, URL bundleFile) throws Exception { - if (logger.isLoggable(Level.FINE)) { - logger.fine("Installing bundle: " + bundleFile); - } - long start = System.currentTimeMillis(); - - File file = JarFileFinder.toFile(bundleFile); - if (file != null && file.isDirectory()) { - boolean isOSGiBundle = false; - File mf = new File(file, "META-INF/MANIFEST.MF"); - if (mf.isFile()) { - Manifest manifest = new Manifest(); - manifest.read(new FileInputStream(mf)); - isOSGiBundle = manifest != null && manifest.getMainAttributes().getValue(BUNDLE_SYMBOLICNAME) != null; - } - if (isOSGiBundle) { - Bundle bundle = bundleContext.installBundle(bundleFile.toString()); - if (logger.isLoggable(Level.FINE)) { - logger.fine("Bundle installed in " + (System.currentTimeMillis() - start) + " ms: " + bundleFile); - } - tuscanyBundles.add(bundle); - return bundle; - } else { - return null; - } - } else if (file != null && !file.exists()) { - return null; - } - Manifest manifest = readManifest(bundleFile); - boolean isOSGiBundle = manifest != null && manifest.getMainAttributes().getValue(BUNDLE_SYMBOLICNAME) != null; - - if (!isOSGiBundle) { - // return null; - manifest = updateBundleManifest(bundleFile, manifest); - } - - String symbolicName = manifest.getMainAttributes().getValue(BUNDLE_SYMBOLICNAME); - if (symbolicName != null) { - int index = symbolicName.indexOf(';'); - if (index != -1) { - symbolicName = symbolicName.substring(0, index); - } - } - String version = manifest.getMainAttributes().getValue(BUNDLE_VERSION); - Bundle bundle = findBundle(bundleContext, symbolicName, version); - if (bundle != null) { - if (logger.isLoggable(Level.FINE)) { - logger.fine("Bundle is already installed: " + symbolicName); - } - return bundle; - } - - String bundleLocation = bundleFile.toString(); - InputStream inStream = null; - if (!isOSGiBundle) { - // We need to repackage the bundle - ByteArrayOutputStream out = new ByteArrayOutputStream(); - JarOutputStream jarOut = new JarOutputStream(out, manifest); - - String classpath = manifest.getMainAttributes().getValue("Bundle-ClassPath"); - boolean embedded = classpath != null && !classpath.trim().equals("."); - if (embedded) { - addFileToJar(bundleFile, jarOut); - } else { - copyJar(bundleFile, jarOut); - } - - jarOut.close(); - inStream = new ByteArrayInputStream(out.toByteArray()); - } else { - // The file itself is already a bundle - inStream = bundleFile.openStream(); - } - - try { - bundle = bundleContext.installBundle(bundleLocation, inStream); - if (logger.isLoggable(Level.FINE)) { - logger.fine("Bundle installed in " + (System.currentTimeMillis() - start) + " ms: " + bundleLocation); - } - tuscanyBundles.add(bundle); - return bundle; - } finally { - inStream.close(); - } - - } - - private Bundle findBundle(BundleContext bundleContext, String symbolicName, String version) { - Bundle[] bundles = bundleContext.getBundles(); - if (version == null) { - version = "0.0.0"; - } - for (Bundle b : bundles) { - String v = (String)b.getHeaders().get(BUNDLE_VERSION); - if (v == null) { - v = "0.0.0"; - } - if (b.getSymbolicName().equals(symbolicName) && (version.equals("0.0.0") || v.equals(version))) { - return b; - } - } - return null; - } - - private String getFileName(URL url) { - String name = url.getPath(); - int index = name.lastIndexOf('/'); - return name.substring(index + 1); - } - - private void addFileToJar(URL file, JarOutputStream jarOut) throws IOException { - JarEntry ze = new JarEntry(getFileName(file)); - jarOut.putNextEntry(ze); - InputStream inStream = file.openStream(); - copy(inStream, jarOut); - inStream.close(); - } - - private void copy(InputStream in, OutputStream out) throws IOException { - byte[] readBuf = new byte[4096]; - int bytesRead; - while ((bytesRead = in.read(readBuf)) > 0) { - out.write(readBuf, 0, bytesRead); - } - } - - private void copyJar(URL in, JarOutputStream jarOut) throws IOException { - JarInputStream jarIn = new JarInputStream(in.openStream()); - ZipEntry ze; - while ((ze = jarIn.getNextEntry()) != null) { - // Skip the MANIFEST.MF - if (ze.getName().equals("META-INF/MANIFEST.MF")) - continue; - jarOut.putNextEntry(ze); - copy(jarIn, jarOut); - } - jarIn.close(); - } - - private Manifest readManifest(URL jarFile) throws IOException { - JarInputStream jar = new JarInputStream(jarFile.openStream()); - // Read the Manifest from the jar file - Manifest manifest = jar.getManifest(); - jar.close(); - - if (manifest == null) { - // Create a new one if no Manifest is found - manifest = new Manifest(); - } - return manifest; - } - - private Manifest updateBundleManifest(URL jarFile, Manifest manifest) throws Exception { - - // Check if we have an associated .mf file - String name = jarFile.toString(); - int index = name.lastIndexOf('.'); - if (index != -1) { - URL mf = new URL(name.substring(0, index) + ".mf"); - try { - InputStream in = mf.openStream(); - manifest.read(in); - in.close(); - } catch (IOException e) { - // Ignore - } - } - - String jarFileName = getFileName(jarFile); - boolean isImmutableJar = false; - for (String immutableJar : immutableJars) { - if (jarFileName.startsWith(immutableJar)) { - isImmutableJar = true; - break; - } - } - - Attributes attributes = manifest.getMainAttributes(); - if (attributes.getValue(BUNDLE_SYMBOLICNAME) == null) { - String bundleSymbolicName = jarFileName; - if (bundleSymbolicName.endsWith(".jar")) { - bundleSymbolicName = bundleSymbolicName.substring(0, bundleSymbolicName.length() - 4); - } - attributes.putValue(BUNDLE_SYMBOLICNAME, bundleSymbolicName); - } else { - // Assume the jar is already a bundle - return null; - } - - if (attributes.getValue("Manifest-Version") == null) { - attributes.putValue("Manifest-Version", "1.0"); - } - - if (attributes.getValue(BUNDLE_MANIFESTVERSION) == null) { - attributes.putValue(BUNDLE_MANIFESTVERSION, "2"); - } - - if (isImmutableJar && attributes.getValue(BUNDLE_CLASSPATH) == null) { - attributes.putValue(BUNDLE_CLASSPATH, ".," + jarFileName); - } - - JarInputStream jar = new JarInputStream(jarFile.openStream()); - HashSet<String> packages = getPackagesInJar(jarFileName, jar); - jar.close(); - String version = getJarVersion(jarFileName); - - // attributes.remove(new Attributes.Name("Require-Bundle")); - // attributes.remove(new Attributes.Name("Import-Package")); - - if (attributes.getValue(BUNDLE_VERSION) == null) { - attributes.putValue(BUNDLE_VERSION, version); - } - // Existing export statements in bundles may contain versions, so they should be used as is - // SDO exports are not sufficient, and should be changed - if (attributes.getValue(EXPORT_PACKAGE) == null || jarFileName.startsWith("tuscany-sdo-impl")) { - String pkgs = packagesToString(packages, version); - if (pkgs.length() > 0) { - attributes.putValue(EXPORT_PACKAGE, pkgs); - attributes.putValue(IMPORT_PACKAGE, packagesToString(packages, null)); - } - // attributes.putValue("Import-Package", packagesToString(packages, null)); - } - - attributes.putValue(DYNAMICIMPORT_PACKAGE, "*"); - return manifest; - } - - private HashSet<String> getPackagesInJar(String bundleName, JarInputStream jar) throws Exception { - HashSet<String> packages = new HashSet<String>(); - ZipEntry entry; - while ((entry = jar.getNextEntry()) != null) { - String entryName = entry.getName(); - if (!entry.isDirectory() && entryName != null && entryName.length() > 0 && !entryName.startsWith(".") - // && !entryName.startsWith("META-INF") - && entryName.lastIndexOf("/") > 0) { - String pkg = entryName.substring(0, entryName.lastIndexOf("/")).replace('/', '.'); - packages.add(pkg); - - } - } - // FIXME: Split package - if (bundleName.startsWith("axis2-adb")) { - packages.remove("org.apache.axis2.util"); - } else if (bundleName.startsWith("axis2-codegen")) { - packages.remove("org.apache.axis2.wsdl"); - packages.remove("org.apache.axis2.wsdl.util"); - } else if (bundleName.startsWith("bsf-all")) { - packages.remove("org.mozilla.javascript"); - } - - return packages; - } - - private String packagesToString(HashSet<String> packages, String version) { - - StringBuilder pkgBuf = new StringBuilder(); - for (String pkg : packages) { - if (pkgBuf.length() > 0) { - pkgBuf.append(','); - } - pkgBuf.append(pkg); - if (version != null && !pkg.startsWith("META-INF.")) { - pkgBuf.append(";version=\""); - pkgBuf.append(version); - pkgBuf.append('\"'); - } - } - return pkgBuf.toString(); - } - - private String getJarVersion(String bundleName) { - Pattern pattern = Pattern.compile("-([0-9.]+)"); - Matcher matcher = pattern.matcher(bundleName); - String version = "1.0.0"; - if (matcher.find()) { - version = matcher.group(); - if (version.endsWith(".")) { - version = version.substring(1, version.length() - 1); - } else { - version = version.substring(1); - } - } - return version; - } - - public BundleContext getBundleContext() { - return bundleContext; - } - public void bundleChanged(BundleEvent event) { } diff --git a/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/LibrariesBundleFileFactoryHook.java b/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/LibrariesBundleFileFactoryHook.java new file mode 100644 index 0000000000..2713dd7f52 --- /dev/null +++ b/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/LibrariesBundleFileFactoryHook.java @@ -0,0 +1,147 @@ +/* + * 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 java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.Enumeration; +import java.util.jar.Manifest; + +import org.eclipse.osgi.baseadaptor.BaseData; +import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry; +import org.eclipse.osgi.baseadaptor.bundlefile.BundleFile; + +/** + * A bundle file factory hook that. + * + * @version $Rev: $ $Date: $ +*/ +public class LibrariesBundleFileFactoryHook implements org.eclipse.osgi.baseadaptor.hooks.BundleFileFactoryHook { + + private Manifest manifest; + + private static class LibrariesBundleFile extends BundleFile { + + private static class ManifestBundleEntry extends BundleEntry { + + private byte[] bytes; + + public ManifestBundleEntry(Manifest manifest) { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + try { + manifest.write(bos); + bytes = bos.toByteArray(); + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + + @Override + public URL getFileURL() { + return null; + } + + @Override + public InputStream getInputStream() throws IOException { + return new ByteArrayInputStream(bytes); + } + + @Override + public URL getLocalURL() { + return null; + } + + @Override + public String getName() { + return "META-INF/MANIFEST.MF"; + } + + @Override + public long getSize() { + return bytes.length; + } + + @Override + public long getTime() { + return -1; + } + + @Override + public byte[] getBytes() throws IOException { + return bytes; + } + } + + private Manifest manifest; + + public LibrariesBundleFile(Object baseFile, Manifest manifest) { + super((File)baseFile); + this.manifest = manifest; + } + + @Override + public void close() throws IOException { + } + + @Override + public boolean containsDir(String dir) { + return false; + } + + @Override + public BundleEntry getEntry(String path) { + if ("META-INF/MANIFEST.MF".equals(path)) { + return new ManifestBundleEntry(manifest); + } + return null; + } + + @Override + public Enumeration getEntryPaths(String path) { + return null; + } + + @Override + public File getFile(String path, boolean nativeCode) { + return null; + } + + @Override + public void open() throws IOException { + } + } + + public LibrariesBundleFileFactoryHook(Manifest manifest) { + this.manifest = manifest; + } + + public BundleFile createBundleFile(Object content, BaseData data, boolean base) throws IOException { + if ("org.apache.tuscany.sca.node.launcher.equinox.libraries".equals(data.getLocation())) { + return new LibrariesBundleFile(content, manifest); + } else { + return null; + } + } + +} diff --git a/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/NodeDaemonLauncher.java b/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/NodeDaemonLauncher.java index c589fdda25..b77382d6a0 100644 --- a/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/NodeDaemonLauncher.java +++ b/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/NodeDaemonLauncher.java @@ -66,13 +66,13 @@ public class NodeDaemonLauncher { // Create a node launcher NodeDaemonLauncher launcher = newInstance(); - EquinoxOSGiHost equinox = null; + EquinoxHost equinox = null; Object node = null; ShutdownThread shutdown = null; try { // Start the OSGi host - equinox = new EquinoxOSGiHost(); + equinox = new EquinoxHost(); equinox.start(); // Start the node @@ -135,9 +135,9 @@ public class NodeDaemonLauncher { private static class ShutdownThread extends Thread { private Object node; - private EquinoxOSGiHost equinox; + private EquinoxHost equinox; - public ShutdownThread(Object node, EquinoxOSGiHost equinox) { + public ShutdownThread(Object node, EquinoxHost equinox) { super(); this.node = node; this.equinox = equinox; diff --git a/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/NodeLauncher.java b/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/NodeLauncher.java index e3313e7bdf..5b12dfca05 100644 --- a/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/NodeLauncher.java +++ b/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/NodeLauncher.java @@ -33,13 +33,13 @@ import java.util.logging.Logger; public class NodeLauncher { static final Logger logger = Logger.getLogger(NodeLauncher.class.getName()); - private EquinoxOSGiHost host; + private EquinoxHost host; /** * Constructs a new node launcher. */ private NodeLauncher() { - host = new EquinoxOSGiHost(); + host = new EquinoxHost(); host.start(); } @@ -118,7 +118,7 @@ public class NodeLauncher { // Create a node launcher NodeLauncher launcher = newInstance(); - EquinoxOSGiHost equinox = launcher.host; + EquinoxHost equinox = launcher.host; Object node = null; ShutdownThread shutdown = null; try { @@ -204,9 +204,9 @@ public class NodeLauncher { private static class ShutdownThread extends Thread { private Object node; - private EquinoxOSGiHost equinox; + private EquinoxHost equinox; - public ShutdownThread(Object node, EquinoxOSGiHost equinox) { + public ShutdownThread(Object node, EquinoxHost equinox) { super(); this.node = node; this.equinox = equinox; diff --git a/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/NodeLauncherUtil.java b/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/NodeLauncherUtil.java index e7373d529b..1ffb987b80 100644 --- a/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/NodeLauncherUtil.java +++ b/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/NodeLauncherUtil.java @@ -19,8 +19,32 @@ package org.apache.tuscany.sca.node.equinox.launcher; +import static org.apache.tuscany.sca.node.equinox.launcher.NodeLauncherUtil.file; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; import java.lang.reflect.Constructor; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.jar.Attributes; +import java.util.jar.JarInputStream; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; import java.util.logging.Level; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import org.osgi.framework.Bundle; +import org.osgi.framework.Constants; /** * Common functions and constants used by the admin components. @@ -172,4 +196,114 @@ 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); + } + } + + static Pattern pattern = Pattern.compile("-([0-9.]+)"); + + private static String version(String jarFile) { + Matcher matcher = pattern.matcher(jarFile); + String version = "1.0.0"; + if (matcher.find()) { + version = matcher.group(); + if (version.endsWith(".")) { + version = version.substring(1, version.length() - 1); + } else { + version = version.substring(1); + } + } + return version; + } + + private static void addPackages(String jarFile, Set<String> packages) throws IOException { + String version = ";version=" + version(jarFile); + ZipInputStream is = new ZipInputStream(new FileInputStream(file(new URL(jarFile)))); + ZipEntry entry; + while ((entry = is.getNextEntry()) != null) { + String entryName = entry.getName(); + if (!entry.isDirectory() && entryName != null && entryName.length() > 0 && + !entryName.startsWith(".") && !entryName.startsWith("META-INF") && + entryName.lastIndexOf("/") > 0) { + String pkg = entryName.substring(0, entryName.lastIndexOf("/")).replace('/', '.') + version; + packages.add(pkg); + } + } + is.close(); + } + + static Manifest libraryManifest(String[] jarFiles) throws IllegalStateException { + try { + + // List exported packages and bundle classpath entries + StringBuffer classpath = new StringBuffer(); + StringBuffer exports = new StringBuffer(); + Set<String> packages = new HashSet<String>(); + for (String jarFile: jarFiles) { + addPackages(jarFile, packages); + classpath.append(jarFile); + classpath.append(','); + } + for (String pkg: packages) { + exports.append(pkg); + exports.append(','); + } + + // Create a manifest + Manifest manifest = new Manifest(); + Attributes attributes = manifest.getMainAttributes(); + attributes.putValue("Manifest-Version", "1.0"); + attributes.putValue(Constants.BUNDLE_MANIFESTVERSION, "2"); + attributes.putValue(Constants.BUNDLE_SYMBOLICNAME, "org.apache.tuscany.sca.node.launcher.equinox.libraries"); + attributes.putValue(Constants.EXPORT_PACKAGE, exports.substring(0, exports.length() -1)); + attributes.putValue(Constants.BUNDLE_CLASSPATH, classpath.substring(0, classpath.length() -1)); + + return manifest; + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + + static String string(Bundle b, boolean verbose) { + StringBuffer sb = new StringBuffer(); + sb.append(b.getBundleId()).append(" ").append(b.getSymbolicName()); + int s = b.getState(); + if ((s & Bundle.UNINSTALLED) != 0) { + sb.append(" UNINSTALLED"); + } + if ((s & Bundle.INSTALLED) != 0) { + sb.append(" INSTALLED"); + } + if ((s & Bundle.RESOLVED) != 0) { + sb.append(" RESOLVED"); + } + if ((s & Bundle.STARTING) != 0) { + sb.append(" STARTING"); + } + if ((s & Bundle.STOPPING) != 0) { + sb.append(" STOPPING"); + } + if ((s & Bundle.ACTIVE) != 0) { + sb.append(" ACTIVE"); + } + + if (verbose) { + sb.append(" ").append(b.getLocation()); + sb.append(" ").append(b.getHeaders()); + } + return sb.toString(); + } } diff --git a/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/NodeServletFilter.java b/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/NodeServletFilter.java deleted file mode 100644 index 08c7401fa3..0000000000 --- a/java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/NodeServletFilter.java +++ /dev/null @@ -1,127 +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 java.io.IOException; -import java.util.logging.Level; -import java.util.logging.Logger; - -import javax.servlet.Filter; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; - -/** - * A Servlet filter that forwards service requests to the Servlets registered with - * the Tuscany ServletHost. - * - * @version $Rev$ $Date$ - */ -public class NodeServletFilter implements Filter { - private static final long serialVersionUID = 1L; - - private static final String NODE_WEB_APP_SERVLET_HOST = "org.apache.tuscany.sca.implementation.node.webapp.NodeWebAppServletHost"; - - private static final Logger logger = Logger.getLogger(NodeServletFilter.class.getName()); - - private ClassLoader runtimeClassLoader; - private Class<?> servletHostClass; - private Object servletHost; - private Filter filter; - - public void init(FilterConfig filterConfig) throws ServletException { - logger.info("Apache Tuscany SCA WebApp Node is starting..."); - - try { - // Get the Tuscany runtime ClassLoader - ClassLoader tccl = Thread.currentThread().getContextClassLoader(); - //runtimeClassLoader = webAppRuntimeClassLoader(getClass().getClassLoader()); - try { - if (runtimeClassLoader != null) { - Thread.currentThread().setContextClassLoader(runtimeClassLoader); - } - - // Load the Tuscany WebApp Servlet host and get the host instance - // for the current webapp - String className = NODE_WEB_APP_SERVLET_HOST; - if (runtimeClassLoader != null) { - servletHostClass = Class.forName(className, true, runtimeClassLoader); - } else { - servletHostClass = Class.forName(className); - } - servletHost = servletHostClass.getMethod("servletHost").invoke(null); - - // Initialize the Servlet host - servletHostClass.getMethod("init", FilterConfig.class).invoke(servletHost, filterConfig); - - // The Servlet host also implements the filter interface - filter = (Filter)servletHost; - - } finally { - Thread.currentThread().setContextClassLoader(tccl); - } - - } catch (Exception e) { - logger.log(Level.SEVERE, "Error Starting SCA WebApp Node", e); - throw new ServletException(e); - } - - logger.info("SCA WebApp Node started."); - } - - public void destroy() { - logger.info("Apache Tuscany WebApp Node stopping..."); - if (servletHost != null) { - ClassLoader tccl = Thread.currentThread().getContextClassLoader(); - try { - if (runtimeClassLoader != null) { - Thread.currentThread().setContextClassLoader(runtimeClassLoader); - } - - servletHostClass.getMethod("destroy").invoke(servletHost); - - } catch (Exception e) { - logger.log(Level.SEVERE, "Error Stopping SCA WebApp Node", e); - } finally { - Thread.currentThread().setContextClassLoader(tccl); - } - } - logger.info("SCA WebApp Node stopped."); - } - - public void doFilter(ServletRequest request, ServletResponse response, javax.servlet.FilterChain chain) - throws IOException, ServletException { - - // Delegate to the Servlet host filter - ClassLoader tccl = Thread.currentThread().getContextClassLoader(); - try { - if (runtimeClassLoader != null) { - Thread.currentThread().setContextClassLoader(runtimeClassLoader); - } - - filter.doFilter(request, response, chain); - - } finally { - Thread.currentThread().setContextClassLoader(tccl); - } - } - -} diff --git a/java/sca/modules/node-launcher-equinox/src/main/resources/hookconfigurators.properties b/java/sca/modules/node-launcher-equinox/src/main/resources/hookconfigurators.properties new file mode 100644 index 0000000000..cf9c0f74df --- /dev/null +++ b/java/sca/modules/node-launcher-equinox/src/main/resources/hookconfigurators.properties @@ -0,0 +1,16 @@ +# 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. +hook.configurators=org.apache.tuscany.sca.node.equinox.launcher.EquinoxHookConfigurator
\ No newline at end of file |