summaryrefslogtreecommitdiffstats
path: root/java/sca/modules/node-launcher-equinox/src/main
diff options
context:
space:
mode:
authorjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2008-09-07 11:25:41 +0000
committerjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2008-09-07 11:25:41 +0000
commit749d5c9a1c6a58fb7ff9078d97afb96039f89b7a (patch)
tree8057292ef3e9d14636a225811090b74f9faab2e8 /java/sca/modules/node-launcher-equinox/src/main
parent252f4d6eecc3cb008a9b8c139bdafdf588ecadc8 (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')
-rw-r--r--java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/DomainManagerLauncher.java8
-rw-r--r--java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/EquinoxHookConfigurator.java58
-rw-r--r--java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/EquinoxHost.java214
-rw-r--r--java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/EquinoxOSGiHost.java178
-rw-r--r--java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/JarFileFinder.java25
-rw-r--r--java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/LauncherBundleActivator.java497
-rw-r--r--java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/LibrariesBundleFileFactoryHook.java147
-rw-r--r--java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/NodeDaemonLauncher.java8
-rw-r--r--java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/NodeLauncher.java10
-rw-r--r--java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/NodeLauncherUtil.java134
-rw-r--r--java/sca/modules/node-launcher-equinox/src/main/java/org/apache/tuscany/sca/node/equinox/launcher/NodeServletFilter.java127
-rw-r--r--java/sca/modules/node-launcher-equinox/src/main/resources/hookconfigurators.properties16
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