From 8b1e44f10b9e1812c160b24c52eae7d411d070f2 Mon Sep 17 00:00:00 2001 From: Stefan Bodewig Date: Fri, 12 Dec 2003 09:41:46 +0000 Subject: [PATCH] Add a cloneVm attribute to CommandlineJava and and . 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-ffa450edef68 --- .../org/apache/tools/ant/taskdefs/Java.java | 13 ++++ .../taskdefs/optional/junit/JUnitTask.java | 13 ++++ .../tools/ant/types/CommandlineJava.java | 60 ++++++++++++++++++- src/main/org/apache/tools/ant/types/Path.java | 11 +++- .../apache/tools/ant/types/PropertySet.java | 10 ++-- 5 files changed, 100 insertions(+), 7 deletions(-) diff --git a/src/main/org/apache/tools/ant/taskdefs/Java.java b/src/main/org/apache/tools/ant/taskdefs/Java.java index 9f947c03a..f491f9e3d 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Java.java +++ b/src/main/org/apache/tools/ant/taskdefs/Java.java @@ -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. + * + *

Doesn't have any effect unless fork is true.

+ * + * @since Ant 1.7 + */ + public void setCloneVm(boolean cloneVm) { + cmdl.setCloneVm(cloneVm); + } + /** * Adds a command-line argument. * diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java b/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java index 4fa47e038..99ba7dd3a 100644 --- a/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java +++ b/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java @@ -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. + * + *

Doesn't have any effect unless fork is true.

+ * + * @since Ant 1.7 + */ + public void setCloneVm(boolean cloneVm) { + commandline.setCloneVm(cloneVm); + } + /** * Creates a new JUnitRunner and enables fork of a new Java VM. * diff --git a/src/main/org/apache/tools/ant/types/CommandlineJava.java b/src/main/org/apache/tools/ant/types/CommandlineJava.java index 3bd58fb6b..52bf7d312 100644 --- a/src/main/org/apache/tools/ant/types/CommandlineJava.java +++ b/src/main/org/apache/tools/ant/types/CommandlineJava.java @@ -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 " -> 2 args if (haveClasspath()) { size += 2; } // bootclasspath is "-Xbootclasspath:" -> 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")); + } } diff --git a/src/main/org/apache/tools/ant/types/Path.java b/src/main/org/apache/tools/ant/types/Path.java index c922651b5..60c67761d 100644 --- a/src/main/org/apache/tools/ant/types/Path.java +++ b/src/main/org/apache/tools/ant/types/Path.java @@ -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 <pathelement> 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); diff --git a/src/main/org/apache/tools/ant/types/PropertySet.java b/src/main/org/apache/tools/ant/types/PropertySet.java index 485be383c..c50906dfb 100644 --- a/src/main/org/apache/tools/ant/types/PropertySet.java +++ b/src/main/org/apache/tools/ant/types/PropertySet.java @@ -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) {