Assert.notNull(executionSpec.getName());
Map<String, Object> values = new TreeMap<String, Object>();
- attrs: for (String key : executionSpec.getAttributes().keySet()) {
+ for (String key : executionSpec.getAttributes().keySet()) {
ExecutionSpecAttribute attribute = executionSpec
.getAttributes().get(key);
package org.argeo.slc.core.execution.tasks;
import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.apache.commons.exec.CommandLine;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.argeo.slc.SlcException;
import org.springframework.core.io.Resource;
public class JvmProcess extends SystemCall {
+ private final static Log log = LogFactory.getLog(JvmProcess.class);
+
private Properties systemProperties = new Properties();
private List<Resource> classpath = new ArrayList<Resource>();
private List<Resource> pBootClasspath = new ArrayList<Resource>();
cl = new CommandLine("java");
if (pBootClasspath.size() > 0) {
- StringBuffer buf = new StringBuffer("-Xbootclasspath/p:");
+ StringBuffer buf = new StringBuffer("-Xbootclasspath/p");
for (Resource res : pBootClasspath) {
- if (buf.length() != 0)
- buf.append(File.pathSeparatorChar);
+ buf.append(File.pathSeparatorChar);
buf.append(asFile(res));
}
cl.addArgument(buf.toString());
cl.addArgument(arg);
}
+ if (log.isDebugEnabled())
+ log.debug("Command line:\n" + cl.toString() + "\n");
+
return cl;
}
protected File asFile(Resource res) {
- // TODO: implements local copy
try {
return res.getFile().getCanonicalFile();
+ } catch (FileNotFoundException e) {
+ return copyToTempFile(res);
} catch (IOException e) {
throw new SlcException("Cannot convert resource to file", e);
}
}
+ protected File copyToTempFile(Resource res) {
+ File tempFile;
+ FileOutputStream fos;
+ try {
+ tempFile = File.createTempFile("slcJvmProcess-", res.getFilename());
+ tempFile.deleteOnExit();
+ fos = new FileOutputStream(tempFile);
+ IOUtils.copy(res.getInputStream(), fos);
+ } catch (IOException e) {
+ throw new SlcException("Cannot copy " + res + " to temp file.", e);
+ }
+ IOUtils.closeQuietly(fos);
+ return tempFile;
+ }
+
public Properties getSystemProperties() {
return systemProperties;
}
<Import-Package>
org.w3c.dom;version="0.0.0",
javax.xml.*;version="0.0.0",
- org.apache.xerces.jaxp,
+ *
+ </Import-Package>
+ <!--
+ <Import-Package> org.w3c.dom;version="0.0.0",
+ javax.xml.*;version="0.0.0", org.apache.xerces.jaxp,
org.springframework.beans.factory;version="2.0",
org.springframework.beans.factory.support;version="2.0",
org.springframework.beans.factory.xml;version="2.0",
org.springframework.context;version="2.0",
org.springframework.context.support;version="2.0",
- org.springframework.core.io;version="2.0",
- *
- </Import-Package>
- <Spring-Context>*;create-asynchronously:=false</Spring-Context>
+ org.springframework.core.io;version="2.0", * </Import-Package>
+ <Spring-Context>*;create-asynchronously:=false</Spring-Context>
+ -->
</instructions>
</configuration>
</plugin>
--- /dev/null
+package org.argeo.slc.lib.detached;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.core.execution.tasks.JvmProcess;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.context.ResourceLoaderAware;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.osgi.context.BundleContextAware;
+
+public class DetachedLauncher extends JvmProcess implements BundleContextAware,
+ InitializingBean, ResourceLoaderAware {
+ private final static Log log = LogFactory.getLog(DetachedLauncher.class);
+
+ private BundleContext bundleContext = null;
+ private ResourceLoader resourceLoader = null;
+
+ private Resource osgiFramework = null;
+ private String osgibootBundleName = "org.argeo.slc.osgiboot";
+ private String equinoxBundleName = "org.eclipse.osgi";
+ private String xmlapisBundleName = "com.springsource.org.apache.xmlcommons";
+ private String xercesBundleName = "com.springsource.org.apache.xerces";
+
+ /**
+ * Required by Spring for JDK 1.4. see
+ * http://forum.springsource.org/showthread.php?t=74555
+ */
+ private Boolean prependXmlJars = false;
+
+ public DetachedLauncher() {
+ // Override defaults
+ setSynchronous(false);
+ setMainClass("org.argeo.slc.osgiboot.Launcher");
+ }
+
+ public void afterPropertiesSet() throws Exception {
+ if (bundleContext == null)
+ throw new SlcException("An OSGi bundle context is required.");
+
+ // Equinox jar
+ if (osgiFramework == null)
+ getClasspath()
+ .add(asResource(System.getProperty("osgi.framework")));
+ else
+ getClasspath().add(osgiFramework);
+
+ StringBuffer osgiLocations = new StringBuffer("");
+ bundles: for (Bundle bundle : bundleContext.getBundles()) {
+ String name = bundle.getSymbolicName();
+
+ // Special bundles
+ if (osgibootBundleName.equals(name))
+ getClasspath().add(findOsgiboot(bundle));
+ else if (equinoxBundleName.equals(name))
+ continue bundles;// skip framework
+ else if (xmlapisBundleName.equals(name) && prependXmlJars)
+ getPBootClasspath().add(asResource(bundle.getLocation()));
+ else if (xercesBundleName.equals(name) && prependXmlJars)
+ getPBootClasspath().add(asResource(bundle.getLocation()));
+
+ if (osgiLocations.length() != 0)
+ osgiLocations.append(',');
+ osgiLocations.append(bundle.getLocation());
+ }
+
+ getSystemProperties().setProperty("osgi.bundles",
+ osgiLocations.toString());
+ }
+
+ protected Resource findOsgiboot(Bundle bundle) {
+ String location = bundle.getLocation();
+ if (location.startsWith("initial@reference:file:"))
+ location = System.getProperty("osgi.install.area") + "/../"
+ + location.substring("initial@reference:file:".length());
+ if (location.charAt(location.length() - 1) == '/')
+ location.substring(0, location.length() - 1);
+ return asResource(location);
+ }
+
+ protected Resource asResource(String location) {
+ Resource res = resourceLoader.getResource(location);
+ if (log.isDebugEnabled())
+ log.debug("Converted " + location + " to " + res);
+ return res;
+ }
+
+ public void setBundleContext(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+
+ public void setResourceLoader(ResourceLoader resourceLoader) {
+ this.resourceLoader = resourceLoader;
+ }
+
+ public void setOsgibootBundleName(String osgibootBundleName) {
+ this.osgibootBundleName = osgibootBundleName;
+ }
+
+ public void setXmlapisBundleName(String xmlapisBundleName) {
+ this.xmlapisBundleName = xmlapisBundleName;
+ }
+
+ public void setXercesBundleName(String xercesBundleName) {
+ this.xercesBundleName = xercesBundleName;
+ }
+
+ public void setOsgiFramework(Resource osgiFramework) {
+ this.osgiFramework = osgiFramework;
+ }
+
+ public void setEquinoxBundleName(String equinoxBundleName) {
+ this.equinoxBundleName = equinoxBundleName;
+ }
+
+ public void setPrependXmlJars(Boolean prependXmlJars) {
+ this.prependXmlJars = prependXmlJars;
+ }
+
+}
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
+/**
+ * An OSGi configurator. See <a
+ * href="http://wiki.eclipse.org/Configurator">http:
+ * //wiki.eclipse.org/Configurator</a>
+ */
public class Activator implements BundleActivator {
public void start(BundleContext bundleContext) throws Exception {
- try {
- OsgiBoot.info("SLC OSGi bootstrap starting...");
- OsgiBoot osgiBoot = new OsgiBoot(bundleContext);
- osgiBoot.installUrls(osgiBoot.getBundlesUrls());
- osgiBoot.installUrls(osgiBoot.getLocationsUrls());
- osgiBoot.installUrls(osgiBoot.getModulesUrls());
- osgiBoot.startBundles();
- OsgiBoot.info("SLC OSGi bootstrap completed");
- } catch (Exception e) {
- e.printStackTrace();
- throw e;
- }
+ OsgiBoot osgiBoot = new OsgiBoot(bundleContext);
+ osgiBoot.bootstrap();
+// try {
+// OsgiBoot.info("SLC OSGi bootstrap starting...");
+// osgiBoot.installUrls(osgiBoot.getBundlesUrls());
+// osgiBoot.installUrls(osgiBoot.getLocationsUrls());
+// osgiBoot.installUrls(osgiBoot.getModulesUrls());
+// osgiBoot.startBundles();
+// OsgiBoot.info("SLC OSGi bootstrap completed");
+// } catch (Exception e) {
+// e.printStackTrace();
+// throw e;
+// }
}
public void stop(BundleContext context) throws Exception {
--- /dev/null
+package org.argeo.slc.osgiboot;
+
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Properties;
+import java.util.Vector;
+
+import org.eclipse.core.runtime.adaptor.EclipseStarter;
+import org.osgi.framework.BundleContext;
+
+public class Launcher {
+
+ public static void main(String[] args) {
+ startMainClass();
+
+ BundleContext bundleContext = null;
+ try {
+ bundleContext = EclipseStarter.startup(args, null);
+ } catch (Exception e) {
+ throw new RuntimeException("Cannot start Equinox.", e);
+ }
+
+ OsgiBoot osgiBoot = new OsgiBoot(bundleContext);
+ osgiBoot.bootstrap();
+ }
+//
+// protected static void startEquinox(Properties config) throws Exception {
+// info("java.home=" + System.getProperty("java.home"));
+// info("java.class.path=" + System.getProperty("java.class.path"));
+//
+// File baseDir = new File(System.getProperty("user.dir"))
+// .getCanonicalFile();
+// String equinoxConfigurationPath = baseDir.getPath() + File.separator
+// + "slc-detached" + File.separator + "equinoxConfiguration";
+//
+// String equinoxArgsLineDefault = "-console -noExit -clean -debug -configuration "
+// + equinoxConfigurationPath;
+// String equinoxArgsLine = config.getProperty(PROP_SLC_OSGI_EQUINOX_ARGS,
+// equinoxArgsLineDefault);
+// // String[] equinoxArgs = { "-console", "-noExit", "-clean", "-debug",
+// // "-configuration", equinoxConfigurationPath };
+// String[] equinoxArgs = equinoxArgsLine.split(" ");
+//
+// BundleContext context = EclipseStarter.startup(equinoxArgs, null);
+// }
+
+ protected static void startMainClass() {
+ Properties config = System.getProperties();
+ String className = config.getProperty("slc.detached.appclass");
+ String[] uiArgs = readArgumentsFromLine(config.getProperty(
+ "slc.detached.appargs", ""));
+ try {
+ // Launch main method using reflection
+ Class clss = Class.forName(className);
+ Class[] mainArgsClasses = new Class[] { uiArgs.getClass() };
+ Object[] mainArgs = { uiArgs };
+ Method mainMethod = clss.getMethod("main", mainArgsClasses);
+ mainMethod.invoke(null, mainArgs);
+ } catch (Exception e) {
+ throw new RuntimeException("Cannot start main class.", e);
+ }
+
+ }
+
+ /**
+ * Transform a line into an array of arguments, taking "" as single
+ * arguments. (nested \" are not supported)
+ */
+ private static String[] readArgumentsFromLine(String lineOrig) {
+
+ String line = lineOrig.trim();// remove trailing spaces
+ // System.out.println("line=" + line);
+ List args = new Vector();
+ StringBuffer curr = new StringBuffer("");
+ boolean inQuote = false;
+ char[] arr = line.toCharArray();
+ for (int i = 0; i < arr.length; i++) {
+ char c = arr[i];
+ switch (c) {
+ case '\"':
+ inQuote = !inQuote;
+ break;
+ case ' ':
+ if (!inQuote) {// otherwise, no break: goes to default
+ if (curr.length() > 0) {
+ args.add(curr.toString());
+ curr = new StringBuffer("");
+ }
+ break;
+ }
+ default:
+ curr.append(c);
+ break;
+ }
+ }
+
+ // Add last arg
+ if (curr.length() > 0) {
+ args.add(curr.toString());
+ curr = null;
+ }
+
+ String[] res = new String[args.size()];
+ for (int i = 0; i < args.size(); i++) {
+ res[i] = args.get(i).toString();
+ // System.out.println("res[i]=" + res[i]);
+ }
+ return res;
+ }
+
+}
this.bundleContext = bundleContext;
}
+ public void bootstrap() {
+ info("SLC OSGi bootstrap starting...");
+ installUrls(getBundlesUrls());
+ installUrls(getLocationsUrls());
+ installUrls(getModulesUrls());
+ startBundles();
+ info("SLC OSGi bootstrap completed");
+ }
+
public void installUrls(List urls) {
Map installedBundles = getInstalledBundles();
for (int i = 0; i < urls.size(); i++) {
}
- public void startBundles() throws Exception {
+ public void startBundles() {
String bundlesToStart = getProperty(PROP_SLC_OSGI_START);
startBundles(bundlesToStart);
}
- public void startBundles(String bundlesToStartStr) throws Exception {
+ public void startBundles(String bundlesToStartStr) {
if (bundlesToStartStr == null)
return;
startBundles(bundlesToStart);
}
- public void startBundles(List bundlesToStart) throws Exception {
+ public void startBundles(List bundlesToStart) {
if (bundlesToStart.size() == 0)
return;
StringTokenizer st = new StringTokenizer(bundleLocations,
File.pathSeparator);
while (st.hasMoreTokens()) {
- urls.add(baseUrl + st.nextToken().trim());
+ urls.add(locationToUrl(baseUrl, st.nextToken().trim()));
}
return urls;
}
for (int i = 0; i < included.size(); i++) {
String fullPath = (String) included.get(i);
if (!excluded.contains(fullPath))
- urls.add(baseUrl + fullPath);
+ urls.add(locationToUrl(baseUrl, fullPath));
}
return urls;
}
}
+ protected String locationToUrl(String baseUrl, String location) {
+ int extInd = location.lastIndexOf('.');
+ String ext = null;
+ if (extInd > 0)
+ ext = location.substring(extInd);
+
+ if (baseUrl.startsWith("reference:") && ".jar".equals(ext))
+ return "file:" + location;
+ else
+ return baseUrl + location;
+ }
+
/** Transforms a relative path in a full system path. */
protected String relativeToFullPath(String basePath, String relativePath) {
return (basePath + '/' + relativePath).replace('/', File.separatorChar);