If set, the forked VM will be configured to match the currently running VM closely. This involves: * copying of all system properties. * copying of the bootclasspath - only if no bootclasspath has been specified explicitly or build.sysclasspath has been set to "only". This is accompanied by a magic system property build.clonevm that can be used to force the attribute to be set. It has to be a system property as CommandlineJava doesn't know about project instances. PR: 25327 git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@275775 13f79535-47bb-0310-9956-ffa450edef68master
@@ -329,6 +329,19 @@ public class Java extends Task { | |||
cmdl.createArgument().setLine(s); | |||
} | |||
/** | |||
* If set, system properties will be copied to the cloned VM - as | |||
* well as the bootclasspath unless you have explicitly specified | |||
* a bootclaspath. | |||
* | |||
* <p>Doesn't have any effect unless fork is true.</p> | |||
* | |||
* @since Ant 1.7 | |||
*/ | |||
public void setCloneVm(boolean cloneVm) { | |||
cmdl.setCloneVm(cloneVm); | |||
} | |||
/** | |||
* Adds a command-line argument. | |||
* | |||
@@ -587,6 +587,19 @@ public class JUnitTask extends Task { | |||
return perm; | |||
} | |||
/** | |||
* If set, system properties will be copied to the cloned VM - as | |||
* well as the bootclasspath unless you have explicitly specified | |||
* a bootclaspath. | |||
* | |||
* <p>Doesn't have any effect unless fork is true.</p> | |||
* | |||
* @since Ant 1.7 | |||
*/ | |||
public void setCloneVm(boolean cloneVm) { | |||
commandline.setCloneVm(cloneVm); | |||
} | |||
/** | |||
* Creates a new JUnitRunner and enables fork of a new Java VM. | |||
* | |||
@@ -104,6 +104,12 @@ public class CommandlineJava implements Cloneable { | |||
*/ | |||
private boolean executeJar = false; | |||
/** | |||
* Whether system properties and bootclasspath shall be cloned. | |||
* @since Ant 1.7 | |||
*/ | |||
private boolean cloneVm = false; | |||
/** | |||
* Specialized Environment class for System properties | |||
*/ | |||
@@ -294,6 +300,15 @@ public class CommandlineJava implements Cloneable { | |||
vmVersion = value; | |||
} | |||
/** | |||
* If set, system properties will be copied to the cloned VM - as | |||
* well as the bootclasspath unless you have explicitly specified | |||
* a bootclaspath. | |||
* @since Ant 1.7 | |||
*/ | |||
public void setCloneVm(boolean cloneVm) { | |||
this.cloneVm = cloneVm; | |||
} | |||
/** | |||
* get the current assertions | |||
@@ -397,10 +412,26 @@ public class CommandlineJava implements Cloneable { | |||
getActualVMCommand().addCommandToList(listIterator); | |||
// properties are part of the vm options... | |||
sysProperties.addDefinitionsToList(listIterator); | |||
if (isCloneVm()) { | |||
SysProperties clonedSysProperties = new SysProperties(); | |||
PropertySet ps = new PropertySet(); | |||
PropertySet.BuiltinPropertySetName sys = | |||
new PropertySet.BuiltinPropertySetName(); | |||
sys.setValue("system"); | |||
ps.appendBuiltin(sys); | |||
clonedSysProperties.addSyspropertyset(ps); | |||
clonedSysProperties.addDefinitionsToList(listIterator); | |||
} | |||
//boot classpath | |||
if (haveBootclasspath(true)) { | |||
listIterator.add("-Xbootclasspath:" + bootclasspath.toString()); | |||
} else if (cloneBootclasspath()) { | |||
listIterator.add("-Xbootclasspath:" + | |||
Path.systemBootClasspath.toString()); | |||
} | |||
//main classpath | |||
if (haveClasspath()) { | |||
listIterator.add("-classpath"); | |||
@@ -489,13 +520,19 @@ public class CommandlineJava implements Cloneable { | |||
* @deprecated please dont use this -it effectively creates the entire command. | |||
*/ | |||
public int size() { | |||
int size = getActualVMCommand().size() + javaCommand.size() + sysProperties.size(); | |||
int size = getActualVMCommand().size() + javaCommand.size() | |||
+ sysProperties.size(); | |||
// cloned system properties | |||
if (isCloneVm()) { | |||
size += System.getProperties().size(); | |||
} | |||
// classpath is "-classpath <classpath>" -> 2 args | |||
if (haveClasspath()) { | |||
size += 2; | |||
} | |||
// bootclasspath is "-Xbootclasspath:<classpath>" -> 1 arg | |||
if (haveBootclasspath(true)) { | |||
if (haveBootclasspath(true) || cloneBootclasspath()) { | |||
size++; | |||
} | |||
// jar execution requires an additional -jar option | |||
@@ -648,4 +685,23 @@ public class CommandlineJava implements Cloneable { | |||
return false; | |||
} | |||
/** | |||
* Should a bootclasspath argument be created to clone the current | |||
* VM settings? | |||
* | |||
* @since Ant 1.7 | |||
*/ | |||
private boolean cloneBootclasspath() { | |||
return isCloneVm() && !vmVersion.startsWith("1.1") | |||
&& Path.systemBootClasspath.size() > 0; | |||
} | |||
/** | |||
* Has the cloneVm attribute or the magic property build.clonevm been set? | |||
* | |||
* @since 1.7 | |||
*/ | |||
private boolean isCloneVm() { | |||
return cloneVm || "true".equals(System.getProperty("build.clonevm")); | |||
} | |||
} |
@@ -104,6 +104,15 @@ public class Path extends DataType implements Cloneable { | |||
new Path(null, System.getProperty("java.class.path")); | |||
/** | |||
* The system bootclassspath as a Path object. | |||
* | |||
* @since Ant 1.7 | |||
*/ | |||
public static Path systemBootClasspath = | |||
new Path(null, System.getProperty("sun.boot.class.path")); | |||
/** | |||
* Helper class, holds the nested <code><pathelement></code> values. | |||
*/ | |||
@@ -404,7 +413,7 @@ public class Path extends DataType implements Cloneable { | |||
public static String[] translatePath(Project project, String source) { | |||
final Vector result = new Vector(); | |||
if (source == null) { | |||
return new String[0]; | |||
return new String[0]; | |||
} | |||
PathTokenizer tok = new PathTokenizer(source); | |||
@@ -194,13 +194,15 @@ public class PropertySet extends DataType { | |||
public Properties getProperties() { | |||
Vector names = null; | |||
Project prj = getProject(); | |||
Hashtable props = | |||
prj == null ? System.getProperties() : prj.getProperties(); | |||
if (getDynamic() || cachedNames == null) { | |||
names = new Vector(); // :TODO: should be a Set! | |||
if (isReference()) { | |||
getRef().addPropertyNames(names, prj.getProperties()); | |||
getRef().addPropertyNames(names, props); | |||
} else { | |||
addPropertyNames(names, prj.getProperties()); | |||
addPropertyNames(names, props); | |||
} | |||
if (!getDynamic()) { | |||
@@ -218,7 +220,7 @@ public class PropertySet extends DataType { | |||
Properties properties = new Properties(); | |||
for (Enumeration e = names.elements(); e.hasMoreElements();) { | |||
String name = (String) e.nextElement(); | |||
String value = prj.getProperty(name); | |||
String value = (String) props.get(name); | |||
if (mapper != null) { | |||
String[] newname = mapper.mapFileName(name); | |||
if (newname != null) { | |||
@@ -243,7 +245,7 @@ public class PropertySet extends DataType { | |||
for (Enumeration e = ptyRefs.elements(); e.hasMoreElements();) { | |||
PropertyRef ref = (PropertyRef) e.nextElement(); | |||
if (ref.name != null) { | |||
if (prj.getProperty(ref.name) != null) { | |||
if (prj != null && prj.getProperty(ref.name) != null) { | |||
names.addElement(ref.name); | |||
} | |||
} else if (ref.prefix != null) { | |||