Merge branch 'wala' into master

This commit is contained in:
Juergen Graf 2014-04-09 17:02:26 +02:00
commit 9fac9e9a30
21 changed files with 363 additions and 93 deletions

30
.gitignore vendored
View File

@ -1,25 +1,23 @@
*.class
*.DS_Store
*~
*.swp
*.class
*.out
*.swp
*/bin/*
com.ibm.wala.core/dat/wala.properties
com.ibm.wala.cast.java.test.data/src/JLex/
com.ibm.wala.cast.js.rhino/lib/
com.ibm.wala.cast.js/lib/
com.ibm.wala.cast.js.rhino.test/2009_swine_flu_outbreak
com.ibm.wala.cast.js.rhino.test/*.html
com.ibm.wala.cast.js.test/examples-src/ajaxslt/
com.ibm.wala.cast.java.polyglot/lib/
.metadata/
*~
.metadata/
com.ibm.wala.cast.java.polyglot/lib/
com.ibm.wala.cast.java.test.data/src/JLex/
com.ibm.wala.cast.java.test/testdata/
com.ibm.wala.cast.js.html.nu_validator/lib/
com.ibm.wala.cast.js.rhino.test/*.html
com.ibm.wala.cast.js.rhino.test/2009_swine_flu_outbreak
com.ibm.wala.cast.js.rhino/lib/
com.ibm.wala.cast.js.test/examples-src/ajaxslt/
com.ibm.wala.cast.js/lib/
com.ibm.wala.core.testdata/@dot/
com.ibm.wala.core.testdata/lib/
com.ibm.wala.cast.js.html.nu_validator/lib/
com.ibm.wala.cast.java.test/testdata/
edu.kit.wala.smali.test/out/
com.ibm.wala.core.tests/dat/wala.examples.properties
com.ibm.wala.core/@dot
com.ibm.wala.core/com.ibm.wala.core*.jar
com.ibm.wala.core/dat/wala.properties
edu.kit.wala.smali.test/out/

View File

@ -387,8 +387,8 @@ public class TypeInference extends SSAInference<TypeVariable> implements FixedPo
TypeAbstraction lhsType = lhs.getType();
TypeAbstraction meet = TypeAbstraction.TOP;
for (int i = 0; i < rhs.length; i++) {
if (rhs[i] != null && ((TypeVariable)rhs[i]).getType() != null) {
TypeVariable r = (TypeVariable) rhs[i];
if (rhs[i] != null && rhs[i].getType() != null) {
TypeVariable r = rhs[i];
meet = meet.meet(r.getType());
}
}

View File

@ -856,10 +856,6 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
System.err.println("visitGet " + field);
}
// skip getfields of primitive type (optimisation)
if (field.getFieldType().isPrimitiveType()) {
return;
}
PointerKey def = getPointerKeyForLocal(lval);
assert def != null;
@ -871,6 +867,23 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
if (f == null) {
return;
}
if(isStatic){
IClass klass = getClassHierarchy().lookupClass(field.getDeclaringClass());
if (klass == null) {
} else {
// side effect of getstatic: may call class initializer
if (DEBUG) {
System.err.println("getstatic call class init " + klass);
}
processClassInitializer(klass);
}
}
// skip getfields of primitive type (optimisation)
if (field.getFieldType().isPrimitiveType()) {
return;
}
if (hasNoInterestingUses(lval)) {
system.recordImplicitPointsToSet(def);
@ -878,15 +891,6 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
if (isStatic) {
PointerKey fKey = getPointerKeyForStaticField(f);
system.newConstraint(def, assignOperator, fKey);
IClass klass = getClassHierarchy().lookupClass(field.getDeclaringClass());
if (klass == null) {
} else {
// side effect of getstatic: may call class initializer
if (DEBUG) {
System.err.println("getstatic call class init " + klass);
}
processClassInitializer(klass);
}
} else {
PointerKey refKey = getPointerKeyForLocal(ref);
// if (!supportFullPointerFlowGraph &&

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.ibm.wala.ide.jsdt.tests</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.pde.PluginNature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,11 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6

View File

@ -0,0 +1,17 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: JSDT Tests
Bundle-SymbolicName: com.ibm.wala.ide.jsdt.tests
Bundle-Version: 1.0.0.qualifier
Require-Bundle: com.ibm.wala.core;bundle-version="1.1.3",
org.junit4;bundle-version="4.5.0",
com.ibm.wala.cast;bundle-version="1.0.0",
com.ibm.wala.cast.js;bundle-version="1.0.0",
com.ibm.wala.cast.js.rhino;bundle-version="1.0.0",
com.ibm.wala.ide.jsdt;bundle-version="1.0.0",
org.eclipse.wst.jsdt.core;bundle-version="1.1.202",
org.eclipse.equinox.common;bundle-version="3.6.100",
com.ibm.wala.ide.tests;bundle-version="1.1.3",
org.eclipse.core.runtime;bundle-version="3.8.0"
Bundle-ActivationPolicy: lazy
Bundle-Activator: com.ibm.wala.ide.jsdt.tests.Activator

View File

@ -0,0 +1,3 @@
source.. = src/
bin.includes = META-INF/,\
.

File diff suppressed because one or more lines are too long

View File

@ -14,7 +14,7 @@
<booleanAttribute key="includeOptional" value="true"/>
<stringAttribute key="location" value="${workspace_loc}/../junit-workspace"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/com.ibm.wala.ide.tests/src/com/ibm/wala/ide/test/WLProjectScopeTest.java"/>
<listEntry value="/com.ibm.wala.ide.jsdt.tests/src/com/ibm/wala/ide/jsdt/tests/WLProjectScopeTest.java"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="1"/>
@ -25,10 +25,10 @@
<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.launching.macosx.MacOSXType/Java SE 6"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.ibm.wala.ide.test.WLProjectScopeTest"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.ibm.wala.ide.jsdt.tests.WLProjectScopeTest"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.ibm.wala.ide.tests"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.ibm.wala.ide.jsdt.tests"/>
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xms40m -XX:MaxPermSize=128m -Xmx2048m -Xdock:icon=../Resources/Eclipse.icns -XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts"/>
<stringAttribute key="pde.version" value="3.3"/>

View File

@ -1,4 +1,4 @@
package com.ibm.wala.ide.test;
package com.ibm.wala.ide.jsdt.tests;
import java.io.IOException;
import java.util.Collections;
@ -10,7 +10,6 @@ import org.junit.Assert;
import org.junit.Test;
import com.ibm.wala.cast.ipa.callgraph.CAstAnalysisScope;
import com.ibm.wala.cast.js.client.EclipseJavaScriptAnalysisEngine;
import com.ibm.wala.cast.js.ipa.callgraph.JSCallGraphUtil;
import com.ibm.wala.cast.js.loader.JavaScriptLoader;
import com.ibm.wala.cast.js.translator.CAstRhinoTranslatorFactory;
@ -22,8 +21,6 @@ import com.ibm.wala.ide.util.JavaScriptHeadlessUtil;
import com.ibm.wala.ide.util.JsdtUtil;
import com.ibm.wala.ide.util.JsdtUtil.CGInfo;
import com.ibm.wala.ipa.callgraph.AnalysisScope;
import com.ibm.wala.ipa.callgraph.CallGraphBuilder;
import com.ibm.wala.util.CancelException;
public class AbstractJSProjectScopeTest {

View File

@ -0,0 +1,58 @@
/*******************************************************************************
* Copyright (c) 2008 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package com.ibm.wala.ide.jsdt.tests;
import org.eclipse.core.runtime.Plugin;
import org.osgi.framework.BundleContext;
public class Activator extends Plugin {
// The plug-in ID
public static final String PLUGIN_ID = "com.ibm.wala.ide.jsdt.tests";
// The shared instance
private static Activator plugin;
/**
* The constructor
*/
public Activator() {
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)
*/
public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
*/
public void stop(BundleContext context) throws Exception {
plugin = null;
super.stop(context);
}
/**
* Returns the shared instance
*
* @return the shared instance
*/
public static Activator getDefault() {
return plugin;
}
}

View File

@ -1,4 +1,4 @@
package com.ibm.wala.ide.test;
package com.ibm.wala.ide.jsdt.tests;
import com.ibm.wala.ide.tests.util.EclipseTestUtil.ZippedProjectData;

View File

@ -1,4 +1,4 @@
package com.ibm.wala.ide.test;
package com.ibm.wala.ide.jsdt.tests;
import com.ibm.wala.ide.tests.util.EclipseTestUtil.ZippedProjectData;

View File

@ -14,14 +14,7 @@ Require-Bundle: com.ibm.wala.shrike,
org.eclipse.ui,
org.eclipse.ui.ide,
org.junit4;bundle-version="4.3.1",
org.eclipse.wst.jsdt.core;bundle-version="1.1.4",
com.ibm.wala.cast.js.test;bundle-version="1.0.0",
com.ibm.wala.cast;bundle-version="1.0.0",
com.ibm.wala.cast.js;bundle-version="1.0.0",
com.ibm.wala.cast.js.rhino;bundle-version="1.0.0",
org.eclipse.wst.jsdt.ui;bundle-version="1.1.4",
com.ibm.wala.ide.jdt;bundle-version="1.0.0",
com.ibm.wala.ide.jsdt;bundle-version="1.0.0"
com.ibm.wala.ide.jdt;bundle-version="1.0.0"
Bundle-Localization: plugin
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Bundle-ActivationPolicy: lazy

Binary file not shown.

View File

@ -1,7 +1,11 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
@ -148,12 +152,9 @@ org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
org.eclipse.jdt.core.formatter.indentation.size=2
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert

View File

@ -0,0 +1,43 @@
package com.ibm.wala.util.debug;
/**
* A stop watch that prints log messages.
*
* @author mschaefer
*
*/
public class LoggingStopwatch {
private long start;
/**
* Start the stopwatch.
*/
public void start() {
this.start = System.nanoTime();
}
/**
* Mark the completion of a task, print the time it took to complete,
* and optionally restart the stopwatch.
*
* @param msg message to print
* @param reset whether to restart the stopwatch
* @return the elapsed time in milliseconds
*/
public long mark(String msg, boolean reset) {
long end = System.nanoTime();
long elapsed = (end-start)/1000000;
System.out.println(msg + ": " + elapsed + "ms");
if(reset)
start();
return elapsed;
}
/**
* Convenience method that invokes {@link #mark(String, boolean)} with {@code true}
* as its second argument.
*/
public long mark(String msg) {
return mark(msg, true);
}
}

View File

@ -13,6 +13,7 @@ package com.ibm.wala.util.processes;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Logger;
@ -25,21 +26,31 @@ import com.ibm.wala.util.PlatformUtil;
public class JavaLauncher extends Launcher {
/**
* @param programArgs arguments to be passed to the Java program
* @param mainClass Declaring class of the main() method to run.
* @param classpathEntries Paths that will be added to the default classpath
* @param programArgs
* arguments to be passed to the Java program
* @param mainClass
* Declaring class of the main() method to run.
* @param classpathEntries
* Paths that will be added to the default classpath
*/
public static JavaLauncher make(String programArgs, String mainClass, List<String> classpathEntries, Logger logger) {
return new JavaLauncher(programArgs, mainClass, true, classpathEntries, false, false, logger);
}
/**
* @param programArgs arguments to be passed to the Java program
* @param mainClass Declaring class of the main() method to run.
* @param inheritClasspath Should the spawned process inherit all classpath entries of the currently running process?
* @param classpathEntries Paths that will be added to the default classpath
* @param captureOutput should the launcher capture the stdout from the subprocess?
* @param captureErr should the launcher capture the stderr from the subprocess?
* @param programArgs
* arguments to be passed to the Java program
* @param mainClass
* Declaring class of the main() method to run.
* @param inheritClasspath
* Should the spawned process inherit all classpath entries of the
* currently running process?
* @param classpathEntries
* Paths that will be added to the default classpath
* @param captureOutput
* should the launcher capture the stdout from the subprocess?
* @param captureErr
* should the launcher capture the stderr from the subprocess?
*/
public static JavaLauncher make(String programArgs, String mainClass, boolean inheritClasspath, List<String> classpathEntries,
boolean captureOutput, boolean captureErr, Logger logger) {
@ -60,7 +71,8 @@ public class JavaLauncher extends Launcher {
private final String mainClass;
/**
* Should the spawned process inherit all classpath entries of the currently running process?
* Should the spawned process inherit all classpath entries of the currently
* running process?
*/
private final boolean inheritClasspath;
@ -83,17 +95,17 @@ public class JavaLauncher extends Launcher {
* A {@link Thread} which spins and drains stderr of the running process.
*/
private Thread stdErrDrain;
/**
* Absolute path of the 'java' executable to use.
*/
private String javaExe;
/**
* Extra args to pass to the JVM
*/
private String vmArgs;
private List<String> vmArgs = new ArrayList<String>();
/**
* The last process returned by a call to start() on this object.
*/
@ -110,7 +122,7 @@ public class JavaLauncher extends Launcher {
}
this.javaExe = defaultJavaExe();
}
public String getJavaExe() {
return javaExe;
}
@ -162,24 +174,53 @@ public class JavaLauncher extends Launcher {
public Process start() throws IllegalArgumentException, IOException {
String cp = makeClasspath();
String heap = " -Xmx800M ";
String heap = "-Xmx800M";
// on Mac, need to pass an extra parameter so we can cleanly kill child
// Java process
String signalParam = PlatformUtil.onMacOSX() ? " -Xrs " : "";
String signalParam = PlatformUtil.onMacOSX() ? "-Xrs" : null;
String ea = enableAssertions ? " -ea " : "";
String vmArgs = getVmArgs() == null ? "" : getVmArgs();
List<String> cmd = new ArrayList<String>();
String cmd = javaExe + heap + signalParam + cp + " " + makeLibPath() + " " + ea + " " + vmArgs + " " + getMainClass() + " " + getProgramArgs();
cmd.add(javaExe);
cmd.add(heap);
if (signalParam != null) {
cmd.add(signalParam);
}
cmd.add("-classpath");
cmd.add(cp);
String libPath = makeLibPath();
if (libPath != null) {
cmd.add(libPath);
}
if (enableAssertions) {
cmd.add("-ea");
}
if (vmArgs != null) {
for (String s : vmArgs) {
cmd.add(s);
}
}
cmd.add(getMainClass());
if (getProgramArgs() != null) {
String[] pa = getProgramArgs().split(" ");
for (String s : pa) {
if (s.length() > 0) {
cmd.add(s);
}
}
}
Process p = spawnProcess(cmd);
String[] cmds = new String[cmd.size()];
cmd.toArray(cmds);
Process p = spawnProcess(cmds);
stdErrDrain = isCaptureErr() ? captureStdErr(p) : drainStdErr(p);
stdOutDrain = isCaptureOutput() ? captureStdOut(p) : drainStdOut(p);
lastProcess = p;
return p;
}
public Process getLastProcess() {
return lastProcess;
}
@ -187,7 +228,7 @@ public class JavaLauncher extends Launcher {
private String makeLibPath() {
String libPath = System.getProperty("java.library.path");
if (libPath == null) {
return "";
return null;
} else {
return "-Djava.library.path=" + quoteStringIfNeeded(libPath);
}
@ -195,7 +236,9 @@ public class JavaLauncher extends Launcher {
/**
* Wait for the spawned process to terminate.
* @throws IllegalStateException if the process has not been started
*
* @throws IllegalStateException
* if the process has not been started
*/
public void join() {
if (stdOutDrain == null || stdErrDrain == null) {
@ -224,32 +267,36 @@ public class JavaLauncher extends Launcher {
private String makeClasspath() {
String cp = inheritClasspath ? System.getProperty("java.class.path") : "";
if (getXtraClassPath() == null || getXtraClassPath().isEmpty()) {
return " -classpath " + quoteStringIfNeeded(cp);
return quoteStringIfNeeded(cp);
} else {
for (Iterator<String> it = getXtraClassPath().iterator(); it.hasNext();) {
cp += File.pathSeparatorChar;
cp += (String) it.next();
}
return " -classpath " + quoteStringIfNeeded(cp);
return quoteStringIfNeeded(cp);
}
}
/**
* If the input string contains a space, quote it (for use as a classpath). TODO: Figure out how to make a Mac happy with quotes.
* Trailing separators are unsafe, so we have to escape the last backslash (if present and unescaped), so it doesn't escape the
* closing quote.
* If the input string contains a space, quote it (for use as a classpath).
* TODO: Figure out how to make a Mac happy with quotes. Trailing separators
* are unsafe, so we have to escape the last backslash (if present and
* unescaped), so it doesn't escape the closing quote.
*/
public static String quoteStringIfNeeded(String s) {
s = s.trim();
// s = s.replaceAll(" ", "\\\\ ");
return s;
// Check if there's a space. If not, skip quoting to make Macs happy.
// TODO: Add the check for an escaped space.
if (s.indexOf(' ') == -1) {
return s;
}
if (s.charAt(s.length() - 1) == '\\' && s.charAt(s.length() - 2) != '\\') {
s += '\\'; // Escape the last backslash, so it doesn't escape the quote.
}
return '\"' + s + '\"';
// if (s.indexOf(' ') == -1) {
// return s;
// }
// if (s.charAt(s.length() - 1) == '\\' && s.charAt(s.length() - 2) != '\\')
// {
// s += '\\'; // Escape the last backslash, so it doesn't escape the quote.
// }
// return '\"' + s + '\"';
}
public boolean isEnableAssertions() {
@ -260,12 +307,12 @@ public class JavaLauncher extends Launcher {
this.enableAssertions = enableAssertions;
}
public void setVmArgs(String vmArgs) {
this.vmArgs = vmArgs;
public void addVmArg(String arg) {
this.vmArgs.add(arg);
}
public String getVmArgs() {
return vmArgs;
public List<String> getVmArgs() {
return Collections.unmodifiableList(vmArgs);
}
}

View File

@ -15,6 +15,7 @@ import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;
import java.util.logging.Logger;
@ -107,6 +108,23 @@ public abstract class Launcher {
Process p = Runtime.getRuntime().exec(cmd, ev, getWorkingDir());
return p;
}
/**
* Spawn a process to execute the given command
*
* @return an object representing the process
*/
protected Process spawnProcess(String[] cmd) throws IllegalArgumentException, IOException {
if (cmd == null) {
throw new IllegalArgumentException("cmd cannot be null");
}
if (logger != null) {
logger.info("spawning process " + Arrays.toString(cmd));
}
String[] ev = getEnv() == null ? null : buildEnv(getEnv());
Process p = Runtime.getRuntime().exec(cmd, ev, getWorkingDir());
return p;
}
private String[] buildEnv(Map<String,String> ev) {
String[] result = new String[ev.size()];