|
29 | 29 | import org.apache.tools.ant.taskdefs.Execute; |
30 | 30 | import org.apache.tools.ant.taskdefs.Javac; |
31 | 31 | import org.apache.tools.ant.taskdefs.MatchingTask; |
| 32 | +import org.apache.tools.ant.types.Commandline; |
| 33 | +import org.apache.tools.ant.types.Environment; |
32 | 34 | import org.apache.tools.ant.types.Path; |
| 35 | +import org.apache.tools.ant.types.PropertySet; |
33 | 36 | import org.apache.tools.ant.types.Reference; |
34 | 37 | import org.apache.tools.ant.util.GlobPatternMapper; |
35 | 38 | import org.apache.tools.ant.util.SourceFileScanner; |
|
54 | 57 | import java.util.ArrayList; |
55 | 58 | import java.util.Arrays; |
56 | 59 | import java.util.Collections; |
| 60 | +import java.util.HashSet; |
57 | 61 | import java.util.LinkedHashSet; |
58 | 62 | import java.util.List; |
59 | 63 | import java.util.Map; |
@@ -233,6 +237,12 @@ public class Groovyc extends MatchingTask { |
233 | 237 | private String scriptBaseClass; |
234 | 238 | private String configscript; |
235 | 239 |
|
| 240 | + // GROOVY-11995: forked-mode JVM args / system properties |
| 241 | + private final Commandline jvmArgs = new Commandline(); |
| 242 | + private final Environment sysProperties = new Environment(); |
| 243 | + private final List<PropertySet> sysPropertySets = new ArrayList<>(0); |
| 244 | + private boolean inheritAll; |
| 245 | + |
236 | 246 | private Set<String> scriptExtensions = new LinkedHashSet<>(); |
237 | 247 |
|
238 | 248 | /** |
@@ -702,6 +712,56 @@ public void addConfiguredJavac(final Javac javac) { |
702 | 712 | jointCompilation = true; |
703 | 713 | } |
704 | 714 |
|
| 715 | + /** |
| 716 | + * Adds a JVM argument to be passed to the forked compiler. Only takes effect |
| 717 | + * when {@code fork} is true. Use a nested {@code <jvmarg>} element, e.g. |
| 718 | + * {@code <jvmarg value="--add-opens=java.base/java.lang=ALL-UNNAMED"/>}. |
| 719 | + * |
| 720 | + * @return a new {@code Commandline.Argument} that can be configured by Ant |
| 721 | + * @since 6.0.0 |
| 722 | + */ |
| 723 | + public Commandline.Argument createJvmarg() { |
| 724 | + return jvmArgs.createArgument(); |
| 725 | + } |
| 726 | + |
| 727 | + /** |
| 728 | + * Adds a system property to be passed to the forked compiler as |
| 729 | + * {@code -Dkey=value}. Only takes effect when {@code fork} is true. |
| 730 | + * |
| 731 | + * @param sysp the system property |
| 732 | + * @since 6.0.0 |
| 733 | + */ |
| 734 | + public void addSysproperty(Environment.Variable sysp) { |
| 735 | + sysProperties.addVariable(sysp); |
| 736 | + } |
| 737 | + |
| 738 | + /** |
| 739 | + * Adds a set of system properties (Ant {@code <syspropertyset>}) to be |
| 740 | + * passed to the forked compiler. Only takes effect when {@code fork} is true. |
| 741 | + * |
| 742 | + * @param sysp the property set |
| 743 | + * @since 6.0.0 |
| 744 | + */ |
| 745 | + public void addSyspropertyset(PropertySet sysp) { |
| 746 | + sysPropertySets.add(sysp); |
| 747 | + } |
| 748 | + |
| 749 | + /** |
| 750 | + * If true, pass all properties from the parent Ant project to the forked JVM |
| 751 | + * as system properties so they can be read via {@code System.getProperty(name)}. |
| 752 | + * Only takes effect when {@code fork} is true. Defaults to false. |
| 753 | + * <p> |
| 754 | + * For fine-grained control, use a nested {@code <sysproperty>} or |
| 755 | + * {@code <syspropertyset>} instead. Both may be combined; explicit nested |
| 756 | + * entries take precedence on name collision. |
| 757 | + * |
| 758 | + * @param inheritAll true to inherit all Ant properties into the forked JVM |
| 759 | + * @since 6.0.0 |
| 760 | + */ |
| 761 | + public void setInheritAll(boolean inheritAll) { |
| 762 | + this.inheritAll = inheritAll; |
| 763 | + } |
| 764 | + |
705 | 765 | /** |
706 | 766 | * Enable compiler to report stack trace information if a problem occurs |
707 | 767 | * during compilation. Default is false. |
@@ -1092,7 +1152,8 @@ private List<String> extractJointOptions(Path classpath) { |
1092 | 1152 | return jointOptions; |
1093 | 1153 | } |
1094 | 1154 |
|
1095 | | - private void doForkCommandLineList(List<String> commandLineList, Path classpath, String separator) { |
| 1155 | + // package-private (was private) so tests can verify GROOVY-11995 wiring end-to-end |
| 1156 | + void doForkCommandLineList(List<String> commandLineList, Path classpath, String separator) { |
1096 | 1157 | if (forkedExecutable != null && !forkedExecutable.isEmpty()) { |
1097 | 1158 | commandLineList.add(forkedExecutable); |
1098 | 1159 | } else { |
@@ -1142,6 +1203,39 @@ private void doForkCommandLineList(List<String> commandLineList, Path classpath, |
1142 | 1203 | tmpExtension = tmpExtension.substring(1); |
1143 | 1204 | commandLineList.add("-Dgroovy.default.scriptExtension=" + tmpExtension); |
1144 | 1205 | } |
| 1206 | + // GROOVY-11995: user-supplied JVM args / system properties |
| 1207 | + String[] userJvmArgs = jvmArgs.getArguments(); |
| 1208 | + for (String arg : userJvmArgs) { |
| 1209 | + if ("-classpath".equals(arg) || "-cp".equals(arg) || "--class-path".equals(arg) |
| 1210 | + || arg.startsWith("--class-path=")) { |
| 1211 | + throw new BuildException("Setting the JVM classpath via <jvmarg> is not supported " |
| 1212 | + + "(would override the forked compiler's bootstrap classpath). Use the " |
| 1213 | + + "<classpath> nested element instead.", getLocation()); |
| 1214 | + } |
| 1215 | + } |
| 1216 | + Collections.addAll(commandLineList, userJvmArgs); |
| 1217 | + Set<String> sysPropertyNames = new HashSet<>(); |
| 1218 | + for (Environment.Variable v : sysProperties.getVariablesVector()) { |
| 1219 | + sysPropertyNames.add(v.getKey()); |
| 1220 | + commandLineList.add("-D" + v.getKey() + "=" + v.getValue()); |
| 1221 | + } |
| 1222 | + for (PropertySet ps : sysPropertySets) { |
| 1223 | + for (Map.Entry<Object, Object> entry : ps.getProperties().entrySet()) { |
| 1224 | + String key = entry.getKey().toString(); |
| 1225 | + if (sysPropertyNames.add(key)) { |
| 1226 | + commandLineList.add("-D" + key + "=" + entry.getValue()); |
| 1227 | + } |
| 1228 | + } |
| 1229 | + } |
| 1230 | + if (inheritAll) { |
| 1231 | + for (Map.Entry<String, Object> entry : getProject().getProperties().entrySet()) { |
| 1232 | + Object value = entry.getValue(); |
| 1233 | + if (value == null) continue; |
| 1234 | + if (sysPropertyNames.add(entry.getKey())) { |
| 1235 | + commandLineList.add("-D" + entry.getKey() + "=" + value); |
| 1236 | + } |
| 1237 | + } |
| 1238 | + } |
1145 | 1239 |
|
1146 | 1240 | commandLineList.add(FileSystemCompilerFacade.class.getName()); |
1147 | 1241 | commandLineList.add("--classpath"); |
|
0 commit comments