@@ -52,6 +52,8 @@ public class CommandlineJava implements Cloneable {
private SysProperties sysProperties = new SysProperties();
private Path classpath = null;
private Path bootclasspath = null;
private Path modulepath = null;
private Path upgrademodulepath = null;
private String vmVersion;
private String maxMemory = null;
/**
@@ -60,10 +62,11 @@ public class CommandlineJava implements Cloneable {
private Assertions assertions = null;
/**
* Indicate whether it will execute a jar file or not, in this case
* the first vm option must be a -jar and the 'executable' is a jar file.
* Indicate whether it will execute a jar file, module or main class.
* In this case of jar the first vm option must be a -jar and the 'executable' is a jar file.
* In case of module the first vm option is -m and the 'executable' is 'module/mainClass'.
*/
private boolean executeJar = fals e;
private ExecutableType executableTyp e;
/**
* Whether system properties and bootclasspath shall be cloned.
@@ -320,7 +323,7 @@ public class CommandlineJava implements Cloneable {
*/
public void setJar(String jarpathname) {
javaCommand.setExecutable(jarpathname);
executeJar = true ;
executableType = ExecutableType.JAR ;
}
/**
@@ -330,7 +333,7 @@ public class CommandlineJava implements Cloneable {
* @see #getClassname()
*/
public String getJar() {
if (executeJar ) {
if (executableType == ExecutableType.JAR ) {
return javaCommand.getExecutable();
}
return null;
@@ -341,8 +344,14 @@ public class CommandlineJava implements Cloneable {
* @param classname the fully qualified classname.
*/
public void setClassname(String classname) {
javaCommand.setExecutable(classname);
executeJar = false;
if (executableType == ExecutableType.MODULE) {
javaCommand.setExecutable(createModuleClassPair(
parseModuleFromModuleClassPair(javaCommand.getExecutable()),
classname));
} else {
javaCommand.setExecutable(classname);
executableType = ExecutableType.CLASS;
}
}
/**
@@ -351,8 +360,55 @@ public class CommandlineJava implements Cloneable {
* @see #getJar()
*/
public String getClassname() {
if (!executeJar) {
return javaCommand.getExecutable();
if (executableType != null) {
switch (executableType) {
case CLASS:
return javaCommand.getExecutable();
case MODULE:
return parseClassFromModuleClassPair(javaCommand.getExecutable());
}
}
return null;
}
/**
* Set the module to execute.
* @param module the module name.
* @since ???
*/
public void setModule(final String module) {
if (executableType == null) {
javaCommand.setExecutable(module);
} else {
switch (executableType) {
case JAR:
javaCommand.setExecutable(module);
break;
case CLASS:
javaCommand.setExecutable(createModuleClassPair(
module,
javaCommand.getExecutable()));
break;
case MODULE:
javaCommand.setExecutable(createModuleClassPair(
module,
parseClassFromModuleClassPair(javaCommand.getExecutable())));
break;
}
}
executableType = ExecutableType.MODULE;
}
/**
* Get the name of the module to be run.
* @return the name of the module to run or <tt>null</tt> if there is no module.
* @see #getJar()
* @see #getClassname()
* @since ???
*/
public String getModule() {
if(executableType == ExecutableType.MODULE) {
return parseModuleFromModuleClassPair(javaCommand.getExecutable());
}
return null;
}
@@ -382,6 +438,32 @@ public class CommandlineJava implements Cloneable {
return bootclasspath;
}
/**
* Create a modulepath.
* @param p the project to use to create the path.
* @return a path to be configured.
* @since ???
*/
public Path createModulepath(Project p) {
if (modulepath == null) {
modulepath = new Path(p);
}
return modulepath;
}
/**
* Create an upgrademodulepath.
* @param p the project to use to create the path.
* @return a path to be configured.
* @since ???
*/
public Path createUpgrademodulepath(Project p) {
if (upgrademodulepath == null) {
upgrademodulepath = new Path(p);
}
return upgrademodulepath;
}
/**
* Get the vm version.
* @return the vm version.
@@ -435,6 +517,18 @@ public class CommandlineJava implements Cloneable {
listIterator.add(
classpath.concatSystemClasspath("ignore").toString());
}
//module path
if (haveModulepath()) {
listIterator.add("-modulepath");
listIterator.add(
modulepath.concatSystemClasspath("ignore").toString());
}
//upgrade module path
if (haveUpgrademodulepath()) {
listIterator.add("-upgrademodulepath");
listIterator.add(
upgrademodulepath.concatSystemClasspath("ignore").toString());
}
//now any assertions are added
if (getAssertions() != null) {
getAssertions().applyAssertions(listIterator);
@@ -443,8 +537,10 @@ public class CommandlineJava implements Cloneable {
// a bug in JDK < 1.4 that forces the jvm type to be specified as the first
// option, it is appended here as specified in the docs even though there is
// in fact no order.
if (executeJar ) {
if (executableType == ExecutableType.JAR ) {
listIterator.add("-jar");
} else if (executableType == ExecutableType.MODULE) {
listIterator.add("-m");
}
// this is the classname to run as well as its arguments.
// in case of 'executeJar', the executable is a jar file.
@@ -531,7 +627,7 @@ public class CommandlineJava implements Cloneable {
size++;
}
// jar execution requires an additional -jar option
if (executeJar ) {
if (executableType == ExecutableType.JAR || executableType == ExecutableType.MODULE ) {
size++;
}
//assertions take up space too
@@ -573,6 +669,24 @@ public class CommandlineJava implements Cloneable {
return bootclasspath;
}
/**
* Get the modulepath.
* @return modulepath or null.
* @since ???
*/
public Path getModulepath() {
return modulepath;
}
/**
* Get the upgrademodulepath.
* @return upgrademodulepath or null.
* @since ???
*/
public Path getUpgrademodulepath() {
return upgrademodulepath;
}
/**
* Cache current system properties and set them to those in this
* Java command.
@@ -617,6 +731,12 @@ public class CommandlineJava implements Cloneable {
if (bootclasspath != null) {
c.bootclasspath = (Path) bootclasspath.clone();
}
if (modulepath != null) {
c.modulepath = (Path) modulepath.clone();
}
if (upgrademodulepath != null) {
c.upgrademodulepath = (Path) upgrademodulepath.clone();
}
if (assertions != null) {
c.assertions = (Assertions) assertions.clone();
}
@@ -660,6 +780,30 @@ public class CommandlineJava implements Cloneable {
return calculateBootclasspath(log).size() > 0;
}
/**
* Determine whether the modulepath has been specified.
* @return true if the modulepath is to be used.
* @since ???
*/
public boolean haveModulepath() {
Path fullClasspath = modulepath != null
? modulepath.concatSystemClasspath("ignore") : null;
return fullClasspath != null
&& fullClasspath.toString().trim().length() > 0;
}
/**
* Determine whether the upgrademodulepath has been specified.
* @return true if the upgrademodulepath is to be used.
* @since ???
*/
public boolean haveUpgrademodulepath() {
Path fullClasspath = upgrademodulepath != null
? upgrademodulepath.concatSystemClasspath("ignore") : null;
return fullClasspath != null
&& fullClasspath.toString().trim().length() > 0;
}
/**
* Calculate the bootclasspath based on the bootclasspath
* specified, the build.sysclasspath and ant.build.clonevm magic
@@ -696,4 +840,66 @@ public class CommandlineJava implements Cloneable {
return cloneVm
|| "true".equals(System.getProperty("ant.build.clonevm"));
}
/**
* Creates JDK 9 main module command line argument.
* @param module the module name.
* @param classname the classname or <code>null</code>.
* @return the main module with optional classname command line argument.
* @since ???
*/
private static String createModuleClassPair(final String module, final String classname) {
return classname == null ?
module :
String.format("%s/%s", module, classname); //NOI18N
}
/**
* Parses a module name from JDK 9 main module command line argument.
* @param moduleClassPair a module with optional classname or <code>null</code>.
* @return the module name or <code>null</code>.
* @since ???
*/
private static String parseModuleFromModuleClassPair(final String moduleClassPair) {
if (moduleClassPair == null) {
return null;
}
final String[] moduleAndClass = moduleClassPair.split("/"); //NOI18N
return moduleAndClass[0];
}
/**
* Parses a classname from JDK 9 main module command line argument.
* @param moduleClassPair a module with optional classname or <code>null</code>.
* @return the classname or <code>null</code>.
* @since ???
*/
private static String parseClassFromModuleClassPair(final String moduleClassPair) {
if (moduleClassPair == null) {
return null;
}
final String[] moduleAndClass = moduleClassPair.split("/"); //NOI18N
return moduleAndClass.length == 2 ?
moduleAndClass[1] :
null;
}
/**
* Type of execution.
* @since ???
*/
private enum ExecutableType {
/**
* Main class execution.
*/
CLASS,
/**
* Jar file execution.
*/
JAR,
/**
* Module execution.
*/
MODULE
}
}