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) { | |||