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); | 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. | * Adds a command-line argument. | ||||
* | * | ||||
@@ -587,6 +587,19 @@ public class JUnitTask extends Task { | |||||
return perm; | 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. | * 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; | 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 | * Specialized Environment class for System properties | ||||
*/ | */ | ||||
@@ -294,6 +300,15 @@ public class CommandlineJava implements Cloneable { | |||||
vmVersion = value; | 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 | * get the current assertions | ||||
@@ -397,10 +412,26 @@ public class CommandlineJava implements Cloneable { | |||||
getActualVMCommand().addCommandToList(listIterator); | getActualVMCommand().addCommandToList(listIterator); | ||||
// properties are part of the vm options... | // properties are part of the vm options... | ||||
sysProperties.addDefinitionsToList(listIterator); | 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 | //boot classpath | ||||
if (haveBootclasspath(true)) { | if (haveBootclasspath(true)) { | ||||
listIterator.add("-Xbootclasspath:" + bootclasspath.toString()); | listIterator.add("-Xbootclasspath:" + bootclasspath.toString()); | ||||
} else if (cloneBootclasspath()) { | |||||
listIterator.add("-Xbootclasspath:" + | |||||
Path.systemBootClasspath.toString()); | |||||
} | } | ||||
//main classpath | //main classpath | ||||
if (haveClasspath()) { | if (haveClasspath()) { | ||||
listIterator.add("-classpath"); | listIterator.add("-classpath"); | ||||
@@ -489,13 +520,19 @@ public class CommandlineJava implements Cloneable { | |||||
* @deprecated please dont use this -it effectively creates the entire command. | * @deprecated please dont use this -it effectively creates the entire command. | ||||
*/ | */ | ||||
public int size() { | 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 | // classpath is "-classpath <classpath>" -> 2 args | ||||
if (haveClasspath()) { | if (haveClasspath()) { | ||||
size += 2; | size += 2; | ||||
} | } | ||||
// bootclasspath is "-Xbootclasspath:<classpath>" -> 1 arg | // bootclasspath is "-Xbootclasspath:<classpath>" -> 1 arg | ||||
if (haveBootclasspath(true)) { | |||||
if (haveBootclasspath(true) || cloneBootclasspath()) { | |||||
size++; | size++; | ||||
} | } | ||||
// jar execution requires an additional -jar option | // jar execution requires an additional -jar option | ||||
@@ -648,4 +685,23 @@ public class CommandlineJava implements Cloneable { | |||||
return false; | 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")); | 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. | * 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) { | public static String[] translatePath(Project project, String source) { | ||||
final Vector result = new Vector(); | final Vector result = new Vector(); | ||||
if (source == null) { | if (source == null) { | ||||
return new String[0]; | |||||
return new String[0]; | |||||
} | } | ||||
PathTokenizer tok = new PathTokenizer(source); | PathTokenizer tok = new PathTokenizer(source); | ||||
@@ -194,13 +194,15 @@ public class PropertySet extends DataType { | |||||
public Properties getProperties() { | public Properties getProperties() { | ||||
Vector names = null; | Vector names = null; | ||||
Project prj = getProject(); | Project prj = getProject(); | ||||
Hashtable props = | |||||
prj == null ? System.getProperties() : prj.getProperties(); | |||||
if (getDynamic() || cachedNames == null) { | if (getDynamic() || cachedNames == null) { | ||||
names = new Vector(); // :TODO: should be a Set! | names = new Vector(); // :TODO: should be a Set! | ||||
if (isReference()) { | if (isReference()) { | ||||
getRef().addPropertyNames(names, prj.getProperties()); | |||||
getRef().addPropertyNames(names, props); | |||||
} else { | } else { | ||||
addPropertyNames(names, prj.getProperties()); | |||||
addPropertyNames(names, props); | |||||
} | } | ||||
if (!getDynamic()) { | if (!getDynamic()) { | ||||
@@ -218,7 +220,7 @@ public class PropertySet extends DataType { | |||||
Properties properties = new Properties(); | Properties properties = new Properties(); | ||||
for (Enumeration e = names.elements(); e.hasMoreElements();) { | for (Enumeration e = names.elements(); e.hasMoreElements();) { | ||||
String name = (String) e.nextElement(); | String name = (String) e.nextElement(); | ||||
String value = prj.getProperty(name); | |||||
String value = (String) props.get(name); | |||||
if (mapper != null) { | if (mapper != null) { | ||||
String[] newname = mapper.mapFileName(name); | String[] newname = mapper.mapFileName(name); | ||||
if (newname != null) { | if (newname != null) { | ||||
@@ -243,7 +245,7 @@ public class PropertySet extends DataType { | |||||
for (Enumeration e = ptyRefs.elements(); e.hasMoreElements();) { | for (Enumeration e = ptyRefs.elements(); e.hasMoreElements();) { | ||||
PropertyRef ref = (PropertyRef) e.nextElement(); | PropertyRef ref = (PropertyRef) e.nextElement(); | ||||
if (ref.name != null) { | if (ref.name != null) { | ||||
if (prj.getProperty(ref.name) != null) { | |||||
if (prj != null && prj.getProperty(ref.name) != null) { | |||||
names.addElement(ref.name); | names.addElement(ref.name); | ||||
} | } | ||||
} else if (ref.prefix != null) { | } else if (ref.prefix != null) { | ||||