[junitlauncher] Allow JUnit libraries to be part of the task's classpath 
instead of mandating it to be part of Ant's runtime classpath


Project: http://git-wip-us.apache.org/repos/asf/ant/repo
Commit: http://git-wip-us.apache.org/repos/asf/ant/commit/0cb9d22b
Tree: http://git-wip-us.apache.org/repos/asf/ant/tree/0cb9d22b
Diff: http://git-wip-us.apache.org/repos/asf/ant/diff/0cb9d22b

Branch: refs/heads/master
Commit: 0cb9d22b77dda1dcabba91d4c2a1616d0042d16c
Parents: 134f238
Author: Jaikiran Pai <[email protected]>
Authored: Wed Aug 29 15:26:38 2018 +0530
Committer: Jaikiran Pai <[email protected]>
Committed: Mon Oct 29 18:48:37 2018 +0530

----------------------------------------------------------------------
 .../tools/ant/taskdefs/defaults.properties      |   2 +-
 .../optional/junitlauncher/Constants.java       |  54 ---
 .../optional/junitlauncher/ForkDefinition.java  | 168 -------
 .../optional/junitlauncher/InVMExecution.java   |  50 +++
 .../junitlauncher/JUnitLauncherTask.java        | 376 ----------------
 .../junitlauncher/LaunchDefinition.java         |  69 ---
 .../optional/junitlauncher/LauncherSupport.java | 104 ++++-
 .../junitlauncher/ListenerDefinition.java       | 208 ---------
 .../optional/junitlauncher/NamedTest.java       |  29 --
 .../optional/junitlauncher/SingleTestClass.java | 188 --------
 .../junitlauncher/StandaloneLauncher.java       |  32 +-
 .../optional/junitlauncher/TestClasses.java     | 166 -------
 .../optional/junitlauncher/TestDefinition.java  | 193 --------
 .../junitlauncher/TestExecutionContext.java     |   1 +
 .../optional/junitlauncher/TestRequest.java     |   2 +
 .../junitlauncher/confined/Constants.java       |  54 +++
 .../junitlauncher/confined/ForkDefinition.java  | 142 ++++++
 .../confined/JUnitLauncherClassPathUtil.java    |  76 ++++
 .../confined/JUnitLauncherTask.java             | 436 +++++++++++++++++++
 .../confined/LaunchDefinition.java              |  58 +++
 .../confined/ListenerDefinition.java            | 208 +++++++++
 .../junitlauncher/confined/NamedTest.java       |  29 ++
 .../junitlauncher/confined/SingleTestClass.java | 171 ++++++++
 .../junitlauncher/confined/TestClasses.java     | 152 +++++++
 .../junitlauncher/confined/TestDefinition.java  | 148 +++++++
 .../junitlauncher/confined/package-info.java    |  27 ++
 .../optional/junitlauncher/package-info.java    |  28 ++
 .../junitlauncher/JUnitLauncherTaskTest.java    |   1 +
 28 files changed, 1692 insertions(+), 1480 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ant/blob/0cb9d22b/src/main/org/apache/tools/ant/taskdefs/defaults.properties
----------------------------------------------------------------------
diff --git a/src/main/org/apache/tools/ant/taskdefs/defaults.properties 
b/src/main/org/apache/tools/ant/taskdefs/defaults.properties
index c77c200..a78cedb 100644
--- a/src/main/org/apache/tools/ant/taskdefs/defaults.properties
+++ b/src/main/org/apache/tools/ant/taskdefs/defaults.properties
@@ -161,7 +161,7 @@ jjdoc=org.apache.tools.ant.taskdefs.optional.javacc.JJDoc
 jjtree=org.apache.tools.ant.taskdefs.optional.javacc.JJTree
 junit=org.apache.tools.ant.taskdefs.optional.junit.JUnitTask
 junitreport=org.apache.tools.ant.taskdefs.optional.junit.XMLResultAggregator
-junitlauncher=org.apache.tools.ant.taskdefs.optional.junitlauncher.JUnitLauncherTask
+junitlauncher=org.apache.tools.ant.taskdefs.optional.junitlauncher.confined.JUnitLauncherTask
 native2ascii=org.apache.tools.ant.taskdefs.optional.Native2Ascii
 netrexxc=org.apache.tools.ant.taskdefs.optional.NetRexxC
 propertyfile=org.apache.tools.ant.taskdefs.optional.PropertyFile

http://git-wip-us.apache.org/repos/asf/ant/blob/0cb9d22b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/Constants.java
----------------------------------------------------------------------
diff --git 
a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/Constants.java 
b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/Constants.java
deleted file mode 100644
index a8b501c..0000000
--- 
a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/Constants.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- */
-
-package org.apache.tools.ant.taskdefs.optional.junitlauncher;
-
-/**
- * Constants used within the junitlauncher task
- */
-final class Constants {
-
-    static final int FORK_EXIT_CODE_SUCCESS = 0;
-    static final int FORK_EXIT_CODE_EXCEPTION = 1;
-    static final int FORK_EXIT_CODE_TESTS_FAILED = 2;
-    static final int FORK_EXIT_CODE_TIMED_OUT = 3;
-
-    static final String ARG_PROPERTIES = "--properties";
-    static final String ARG_LAUNCH_DEFINITION = "--launch-definition";
-
-
-    static final String LD_XML_ELM_LAUNCH_DEF = "launch-definition";
-    static final String LD_XML_ELM_TEST = "test";
-    static final String LD_XML_ELM_TEST_CLASSES = "test-classes";
-    static final String LD_XML_ATTR_HALT_ON_FAILURE = "haltOnFailure";
-    static final String LD_XML_ATTR_OUTPUT_DIRECTORY = "outDir";
-    static final String LD_XML_ATTR_INCLUDE_ENGINES = "includeEngines";
-    static final String LD_XML_ATTR_EXCLUDE_ENGINES = "excludeEngines";
-    static final String LD_XML_ATTR_CLASS_NAME = "classname";
-    static final String LD_XML_ATTR_METHODS = "methods";
-    static final String LD_XML_ATTR_PRINT_SUMMARY = "printSummary";
-    static final String LD_XML_ELM_LISTENER = "listener";
-    static final String LD_XML_ATTR_SEND_SYS_ERR = "sendSysErr";
-    static final String LD_XML_ATTR_SEND_SYS_OUT = "sendSysOut";
-    static final String LD_XML_ATTR_LISTENER_RESULT_FILE = "resultFile";
-
-
-    private Constants() {
-
-    }
-}

http://git-wip-us.apache.org/repos/asf/ant/blob/0cb9d22b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/ForkDefinition.java
----------------------------------------------------------------------
diff --git 
a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/ForkDefinition.java
 
b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/ForkDefinition.java
deleted file mode 100644
index c5c95cc..0000000
--- 
a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/ForkDefinition.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- */
-
-package org.apache.tools.ant.taskdefs.optional.junitlauncher;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.Task;
-import org.apache.tools.ant.launch.AntMain;
-import org.apache.tools.ant.types.Commandline;
-import org.apache.tools.ant.types.CommandlineJava;
-import org.apache.tools.ant.types.Environment;
-import org.apache.tools.ant.types.Path;
-import org.apache.tools.ant.types.PropertySet;
-import org.apache.tools.ant.util.LoaderUtils;
-import org.junit.platform.commons.annotation.Testable;
-import org.junit.platform.engine.TestEngine;
-import org.junit.platform.launcher.core.LauncherFactory;
-
-import java.io.File;
-
-/**
- * Represents the {@code fork} element within test definitions of the
- * {@code junitlauncher} task
- */
-public class ForkDefinition {
-
-    private boolean includeAntRuntimeLibraries = true;
-    private boolean includeJUnitPlatformLibraries = true;
-
-    private final CommandlineJava commandLineJava;
-    private final Environment env = new Environment();
-
-    private String dir;
-    private long timeout = -1;
-
-    ForkDefinition() {
-        this.commandLineJava = new CommandlineJava();
-    }
-
-    public void setDir(final String dir) {
-        this.dir = dir;
-    }
-
-    String getDir() {
-        return this.dir;
-    }
-
-    public void setTimeout(final long timeout) {
-        this.timeout = timeout;
-    }
-
-    long getTimeout() {
-        return this.timeout;
-    }
-
-    public void setIncludeJUnitPlatformLibraries(final boolean include) {
-        this.includeJUnitPlatformLibraries = include;
-    }
-
-    public void setIncludeAntRuntimeLibraries(final boolean include) {
-        this.includeAntRuntimeLibraries = include;
-    }
-
-    public Commandline.Argument createJvmArg() {
-        return this.commandLineJava.createVmArgument();
-    }
-
-    public void addConfiguredSysProperty(final Environment.Variable sysProp) {
-        // validate that key/value are present
-        sysProp.validate();
-        this.commandLineJava.addSysproperty(sysProp);
-    }
-
-    public void addConfiguredSysPropertySet(final PropertySet propertySet) {
-        this.commandLineJava.addSyspropertyset(propertySet);
-    }
-
-    public void addConfiguredEnv(final Environment.Variable var) {
-        this.env.addVariable(var);
-    }
-
-    public void addConfiguredModulePath(final Path modulePath) {
-        
this.commandLineJava.createModulepath(modulePath.getProject()).add(modulePath);
-    }
-
-    public void addConfiguredUpgradeModulePath(final Path upgradeModulePath) {
-        
this.commandLineJava.createUpgrademodulepath(upgradeModulePath.getProject()).add(upgradeModulePath);
-    }
-
-    Environment getEnv() {
-        return this.env;
-    }
-
-    /**
-     * Generates a new {@link CommandlineJava} constructed out of the 
configurations set on this
-     * {@link ForkDefinition}
-     *
-     * @param task The junitlaunchertask for which this is a fork definition
-     * @return
-     */
-    CommandlineJava generateCommandLine(final JUnitLauncherTask task) {
-        final CommandlineJava cmdLine;
-        try {
-            cmdLine = (CommandlineJava) this.commandLineJava.clone();
-        } catch (CloneNotSupportedException e) {
-            throw new BuildException(e);
-        }
-        cmdLine.setClassname(StandaloneLauncher.class.getName());
-        // VM arguments
-        final Project project = task.getProject();
-        final Path antRuntimeResourceSources = new Path(project);
-        if (this.includeAntRuntimeLibraries) {
-            addAntRuntimeResourceSource(antRuntimeResourceSources, task, 
toResourceName(AntMain.class));
-            addAntRuntimeResourceSource(antRuntimeResourceSources, task, 
toResourceName(Task.class));
-            addAntRuntimeResourceSource(antRuntimeResourceSources, task, 
toResourceName(JUnitLauncherTask.class));
-        } else {
-            task.log("Excluding Ant runtime libraries from forked JVM 
classpath", Project.MSG_DEBUG);
-        }
-        if (this.includeJUnitPlatformLibraries) {
-            // platform-engine
-            addAntRuntimeResourceSource(antRuntimeResourceSources, task, 
toResourceName(TestEngine.class));
-            // platform-launcher
-            addAntRuntimeResourceSource(antRuntimeResourceSources, task, 
toResourceName(LauncherFactory.class));
-            // platform-commons
-            addAntRuntimeResourceSource(antRuntimeResourceSources, task, 
toResourceName(Testable.class));
-        } else {
-            task.log("Excluding JUnit platform libraries from forked JVM 
classpath", Project.MSG_DEBUG);
-        }
-        final Path classPath = cmdLine.createClasspath(project);
-        classPath.createPath().append(antRuntimeResourceSources);
-
-
-        return cmdLine;
-    }
-
-    private static boolean addAntRuntimeResourceSource(final Path path, final 
JUnitLauncherTask task, final String resource) {
-        final File f = 
LoaderUtils.getResourceSource(task.getClass().getClassLoader(), resource);
-        if (f == null) {
-            task.log("Could not locate source of resource " + resource);
-            return false;
-        }
-        task.log("Found source " + f + " of resource " + resource);
-        path.createPath().setLocation(f);
-        return true;
-    }
-
-    private static String toResourceName(final Class klass) {
-        final String name = klass.getName();
-        return name.replaceAll("\\.", "/") + ".class";
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/ant/blob/0cb9d22b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/InVMExecution.java
----------------------------------------------------------------------
diff --git 
a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/InVMExecution.java
 
b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/InVMExecution.java
new file mode 100644
index 0000000..6b7469a
--- /dev/null
+++ 
b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/InVMExecution.java
@@ -0,0 +1,50 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.junitlauncher;
+
+import org.apache.tools.ant.Project;
+import 
org.apache.tools.ant.taskdefs.optional.junitlauncher.confined.JUnitLauncherTask;
+
+import java.util.Optional;
+import java.util.Properties;
+
+/**
+ * Used during in-vm (non-forked mode) launching of tests
+ */
+public class InVMExecution implements TestExecutionContext {
+
+    private final JUnitLauncherTask task;
+    private final Properties props;
+
+    public InVMExecution(final JUnitLauncherTask task) {
+        this.task = task;
+        this.props = new Properties();
+        this.props.putAll(task.getProject().getProperties());
+    }
+
+    @Override
+    public Properties getProperties() {
+        return this.props;
+    }
+
+    @Override
+    public Optional<Project> getProject() {
+        return Optional.of(this.task.getProject());
+    }
+}

http://git-wip-us.apache.org/repos/asf/ant/blob/0cb9d22b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/JUnitLauncherTask.java
----------------------------------------------------------------------
diff --git 
a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/JUnitLauncherTask.java
 
b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/JUnitLauncherTask.java
deleted file mode 100644
index 028397e..0000000
--- 
a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/JUnitLauncherTask.java
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- */
-package org.apache.tools.ant.taskdefs.optional.junitlauncher;
-
-import org.apache.tools.ant.AntClassLoader;
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.Task;
-import org.apache.tools.ant.taskdefs.Execute;
-import org.apache.tools.ant.taskdefs.ExecuteWatchdog;
-import org.apache.tools.ant.taskdefs.LogOutputStream;
-import org.apache.tools.ant.taskdefs.PumpStreamHandler;
-import org.apache.tools.ant.types.CommandlineJava;
-import org.apache.tools.ant.types.Environment;
-import org.apache.tools.ant.types.Path;
-
-import javax.xml.stream.XMLOutputFactory;
-import javax.xml.stream.XMLStreamWriter;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Optional;
-import java.util.Properties;
-import java.util.concurrent.TimeoutException;
-
-import static 
org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ATTR_HALT_ON_FAILURE;
-import static 
org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ATTR_PRINT_SUMMARY;
-import static 
org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ELM_LAUNCH_DEF;
-
-/**
- * An Ant {@link Task} responsible for launching the JUnit platform for 
running tests.
- * This requires a minimum of JUnit 5, since that's the version in which the 
JUnit platform launcher
- * APIs were introduced.
- * <p>
- * This task in itself doesn't run the JUnit tests, instead the sole 
responsibility of
- * this task is to setup the JUnit platform launcher, build requests, launch 
those requests and then parse the
- * result of the execution to present in a way that's been configured on this 
Ant task.
- * </p>
- * <p>
- * Furthermore, this task allows users control over which classes to select 
for passing on to the JUnit 5
- * platform for test execution. It however, is solely the JUnit 5 platform, 
backed by test engines that
- * decide and execute the tests.
- *
- * @see <a href="https://junit.org/junit5/";>JUnit 5 documentation</a>
- */
-public class JUnitLauncherTask extends Task {
-
-    private Path classPath;
-    private boolean haltOnFailure;
-    private String failureProperty;
-    private boolean printSummary;
-    private final List<TestDefinition> tests = new ArrayList<>();
-    private final List<ListenerDefinition> listeners = new ArrayList<>();
-
-    public JUnitLauncherTask() {
-    }
-
-    @Override
-    public void execute() throws BuildException {
-        if (this.tests.isEmpty()) {
-            return;
-        }
-        final Project project = getProject();
-        for (final TestDefinition test : this.tests) {
-            if (!test.shouldRun(project)) {
-                log("Excluding test " + test + " since it's considered not to 
run " +
-                        "in context of project " + project, Project.MSG_DEBUG);
-                continue;
-            }
-            if (test.getForkDefinition() != null) {
-                forkTest(test);
-            } else {
-                final LauncherSupport launcherSupport = new 
LauncherSupport(new InVMLaunch(Collections.singletonList(test)));
-                launcherSupport.launch();
-            }
-        }
-    }
-
-    /**
-     * Adds the {@link Path} to the classpath which will be used for execution 
of the tests
-     *
-     * @param path The classpath
-     */
-    public void addConfiguredClassPath(final Path path) {
-        if (this.classPath == null) {
-            // create a "wrapper" path which can hold on to multiple
-            // paths that get passed to this method (if at all the task in the 
build is
-            // configured with multiple classpaht elements)
-            this.classPath = new Path(getProject());
-        }
-        this.classPath.add(path);
-    }
-
-    /**
-     * Adds a {@link SingleTestClass} that will be passed on to the underlying 
JUnit platform
-     * for possible execution of the test
-     *
-     * @param test The test
-     */
-    public void addConfiguredTest(final SingleTestClass test) {
-        this.preConfigure(test);
-        this.tests.add(test);
-    }
-
-    /**
-     * Adds {@link TestClasses} that will be passed on to the underlying JUnit 
platform for
-     * possible execution of the tests
-     *
-     * @param testClasses The test classes
-     */
-    public void addConfiguredTestClasses(final TestClasses testClasses) {
-        this.preConfigure(testClasses);
-        this.tests.add(testClasses);
-    }
-
-    /**
-     * Adds a {@link ListenerDefinition listener} which will be enrolled for 
listening to test
-     * execution events
-     *
-     * @param listener The listener
-     */
-    public void addConfiguredListener(final ListenerDefinition listener) {
-        this.listeners.add(listener);
-    }
-
-    public void setHaltonfailure(final boolean haltonfailure) {
-        this.haltOnFailure = haltonfailure;
-    }
-
-    public void setFailureProperty(final String failureProperty) {
-        this.failureProperty = failureProperty;
-    }
-
-    public void setPrintSummary(final boolean printSummary) {
-        this.printSummary = printSummary;
-    }
-
-    private void preConfigure(final TestDefinition test) {
-        if (test.getHaltOnFailure() == null) {
-            test.setHaltOnFailure(this.haltOnFailure);
-        }
-        if (test.getFailureProperty() == null) {
-            test.setFailureProperty(this.failureProperty);
-        }
-    }
-
-    private ClassLoader createClassLoaderForTestExecution() {
-        if (this.classPath == null) {
-            return this.getClass().getClassLoader();
-        }
-        return new AntClassLoader(this.getClass().getClassLoader(), 
getProject(), this.classPath, true);
-    }
-
-
-    private java.nio.file.Path dumpProjectProperties() throws IOException {
-        final java.nio.file.Path propsPath = Files.createTempFile(null, 
"properties");
-        propsPath.toFile().deleteOnExit();
-        final Hashtable<String, Object> props = 
this.getProject().getProperties();
-        final Properties projProperties = new Properties();
-        projProperties.putAll(props);
-        try (final OutputStream os = Files.newOutputStream(propsPath)) {
-            // TODO: Is it always UTF-8?
-            projProperties.store(os, StandardCharsets.UTF_8.name());
-        }
-        return propsPath;
-    }
-
-    private void forkTest(final TestDefinition test) {
-        // create launch command
-        final ForkDefinition forkDefinition = test.getForkDefinition();
-        final CommandlineJava commandlineJava = 
forkDefinition.generateCommandLine(this);
-        if (this.classPath != null) {
-            
commandlineJava.createClasspath(getProject()).createPath().append(this.classPath);
-        }
-        final java.nio.file.Path projectPropsPath;
-        try {
-            projectPropsPath = dumpProjectProperties();
-        } catch (IOException e) {
-            throw new BuildException("Could not create the necessary 
properties file while forking a process" +
-                    " for a test", e);
-        }
-        // --properties <path-to-properties-file>
-        commandlineJava.createArgument().setValue(Constants.ARG_PROPERTIES);
-        
commandlineJava.createArgument().setValue(projectPropsPath.toAbsolutePath().toString());
-
-        final java.nio.file.Path launchDefXmlPath = newLaunchDefinitionXml();
-        try (final OutputStream os = Files.newOutputStream(launchDefXmlPath)) {
-            final XMLStreamWriter writer = 
XMLOutputFactory.newFactory().createXMLStreamWriter(os, "UTF-8");
-            try {
-                writer.writeStartDocument();
-                writer.writeStartElement(LD_XML_ELM_LAUNCH_DEF);
-                if (this.printSummary) {
-                    writer.writeAttribute(LD_XML_ATTR_PRINT_SUMMARY, "true");
-                }
-                if (this.haltOnFailure) {
-                    writer.writeAttribute(LD_XML_ATTR_HALT_ON_FAILURE, "true");
-                }
-                // task level listeners
-                for (final ListenerDefinition listenerDef : this.listeners) {
-                    if (!listenerDef.shouldUse(getProject())) {
-                        continue;
-                    }
-                    // construct the listener definition argument
-                    listenerDef.toForkedRepresentation(writer);
-                }
-                // test definition as XML
-                test.toForkedRepresentation(this, writer);
-                writer.writeEndElement();
-                writer.writeEndDocument();
-            } finally {
-                writer.close();
-            }
-        } catch (Exception e) {
-            throw new BuildException("Failed to construct command line for 
test", e);
-        }
-        // --launch-definition <xml-file-path>
-        
commandlineJava.createArgument().setValue(Constants.ARG_LAUNCH_DEFINITION);
-        
commandlineJava.createArgument().setValue(launchDefXmlPath.toAbsolutePath().toString());
-
-        // launch the process and wait for process to complete
-        final int exitCode = executeForkedTest(forkDefinition, 
commandlineJava);
-        switch (exitCode) {
-            case Constants.FORK_EXIT_CODE_SUCCESS: {
-                // success
-                break;
-            }
-            case Constants.FORK_EXIT_CODE_EXCEPTION: {
-                // process failed with some exception
-                throw new BuildException("Forked test(s) failed with an 
exception");
-            }
-            case Constants.FORK_EXIT_CODE_TESTS_FAILED: {
-                // test has failure(s)
-                try {
-                    if (test.getFailureProperty() != null) {
-                        // if there are test failures and the test is 
configured to set a property in case
-                        // of failure, then set the property to true
-                        
this.getProject().setNewProperty(test.getFailureProperty(), "true");
-                    }
-                } finally {
-                    if (test.isHaltOnFailure()) {
-                        // if the test is configured to halt on test failures, 
throw a build error
-                        final String errorMessage;
-                        if (test instanceof NamedTest) {
-                            errorMessage = "Test " + ((NamedTest) 
test).getName() + " has failure(s)";
-                        } else {
-                            errorMessage = "Some test(s) have failure(s)";
-                        }
-                        throw new BuildException(errorMessage);
-                    }
-                }
-                break;
-            }
-            case Constants.FORK_EXIT_CODE_TIMED_OUT: {
-                throw new BuildException(new TimeoutException("Forked test(s) 
timed out"));
-            }
-        }
-    }
-
-    private int executeForkedTest(final ForkDefinition forkDefinition, final 
CommandlineJava commandlineJava) {
-        final LogOutputStream outStream = new LogOutputStream(this, 
Project.MSG_INFO);
-        final LogOutputStream errStream = new LogOutputStream(this, 
Project.MSG_WARN);
-        final ExecuteWatchdog watchdog = forkDefinition.getTimeout() > 0 ? new 
ExecuteWatchdog(forkDefinition.getTimeout()) : null;
-        final Execute execute = new Execute(new PumpStreamHandler(outStream, 
errStream), watchdog);
-        execute.setCommandline(commandlineJava.getCommandline());
-        execute.setAntRun(getProject());
-        if (forkDefinition.getDir() != null) {
-            
execute.setWorkingDirectory(Paths.get(forkDefinition.getDir()).toFile());
-        }
-        final Environment env = forkDefinition.getEnv();
-        if (env != null && env.getVariables() != null) {
-            execute.setEnvironment(env.getVariables());
-        }
-        log(commandlineJava.describeCommand(), Project.MSG_VERBOSE);
-        int exitCode;
-        try {
-            exitCode = execute.execute();
-        } catch (IOException e) {
-            throw new BuildException("Process fork failed", e, getLocation());
-        }
-        return (watchdog != null && watchdog.killedProcess()) ? 
Constants.FORK_EXIT_CODE_TIMED_OUT : exitCode;
-    }
-
-    private java.nio.file.Path newLaunchDefinitionXml() {
-        final java.nio.file.Path xmlFilePath;
-        try {
-            xmlFilePath = Files.createTempFile(null, ".xml");
-        } catch (IOException e) {
-            throw new BuildException("Failed to construct command line for 
test", e);
-        }
-        xmlFilePath.toFile().deleteOnExit();
-        return xmlFilePath;
-    }
-
-    private final class InVMExecution implements TestExecutionContext {
-
-        private final Properties props;
-
-        InVMExecution() {
-            this.props = new Properties();
-            
this.props.putAll(JUnitLauncherTask.this.getProject().getProperties());
-        }
-
-        @Override
-        public Properties getProperties() {
-            return this.props;
-        }
-
-        @Override
-        public Optional<Project> getProject() {
-            return Optional.of(JUnitLauncherTask.this.getProject());
-        }
-    }
-
-    private final class InVMLaunch implements LaunchDefinition {
-
-        private final TestExecutionContext testExecutionContext = new 
InVMExecution();
-        private final List<TestDefinition> inVMTests;
-        private final ClassLoader executionCL;
-
-        private InVMLaunch(final List<TestDefinition> inVMTests) {
-            this.inVMTests = inVMTests;
-            this.executionCL = createClassLoaderForTestExecution();
-        }
-
-        @Override
-        public List<TestDefinition> getTests() {
-            return this.inVMTests;
-        }
-
-        @Override
-        public List<ListenerDefinition> getListeners() {
-            return listeners;
-        }
-
-        @Override
-        public boolean isPrintSummary() {
-            return printSummary;
-        }
-
-        @Override
-        public boolean isHaltOnFailure() {
-            return haltOnFailure;
-        }
-
-        @Override
-        public ClassLoader getClassLoader() {
-            return this.executionCL;
-        }
-
-        @Override
-        public TestExecutionContext getTestExecutionContext() {
-            return this.testExecutionContext;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/ant/blob/0cb9d22b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/LaunchDefinition.java
----------------------------------------------------------------------
diff --git 
a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/LaunchDefinition.java
 
b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/LaunchDefinition.java
deleted file mode 100644
index 3dd5350..0000000
--- 
a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/LaunchDefinition.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- */
-
-package org.apache.tools.ant.taskdefs.optional.junitlauncher;
-
-import java.util.List;
-
-/**
- * Defines the necessary context for launching the JUnit platform for running
- * tests.
- */
-public interface LaunchDefinition {
-
-    /**
-     * @return Returns the {@link TestDefinition tests} that have to be 
launched
-     *
-     */
-    List<TestDefinition> getTests();
-
-    /**
-     * @return Returns the default {@link ListenerDefinition listeners} that 
will be used
-     * for the tests, if the {@link #getTests() tests} themselves don't 
specify any
-     *
-     */
-    List<ListenerDefinition> getListeners();
-
-    /**
-     * @return Returns true if a summary needs to be printed out after the 
execution of the
-     * tests. False otherwise.
-     *
-     */
-    boolean isPrintSummary();
-
-    /**
-     * @return Returns true if any remaining tests launch need to be stopped 
if any test execution
-     * failed. False otherwise.
-     *
-     */
-    boolean isHaltOnFailure();
-
-    /**
-     * @return Returns the {@link ClassLoader} that has to be used for 
launching and execution of the
-     * tests
-     *
-     */
-    ClassLoader getClassLoader();
-
-    /**
-     * @return Returns the {@link TestExecutionContext} that will be passed to 
{@link TestResultFormatter#setContext(TestExecutionContext)
-     * result formatters} which are applicable during the execution of the 
tests.
-     *
-     */
-    TestExecutionContext getTestExecutionContext();
-}

http://git-wip-us.apache.org/repos/asf/ant/blob/0cb9d22b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/LauncherSupport.java
----------------------------------------------------------------------
diff --git 
a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/LauncherSupport.java
 
b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/LauncherSupport.java
index 1260a3b..e55856a 100644
--- 
a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/LauncherSupport.java
+++ 
b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/LauncherSupport.java
@@ -21,12 +21,22 @@ package 
org.apache.tools.ant.taskdefs.optional.junitlauncher;
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.MagicNames;
 import org.apache.tools.ant.Project;
+import 
org.apache.tools.ant.taskdefs.optional.junitlauncher.confined.LaunchDefinition;
+import 
org.apache.tools.ant.taskdefs.optional.junitlauncher.confined.ListenerDefinition;
+import org.apache.tools.ant.taskdefs.optional.junitlauncher.confined.NamedTest;
+import 
org.apache.tools.ant.taskdefs.optional.junitlauncher.confined.SingleTestClass;
+import 
org.apache.tools.ant.taskdefs.optional.junitlauncher.confined.TestClasses;
+import 
org.apache.tools.ant.taskdefs.optional.junitlauncher.confined.TestDefinition;
 import org.apache.tools.ant.util.FileUtils;
 import org.apache.tools.ant.util.KeepAliveOutputStream;
+import org.junit.platform.engine.Filter;
+import org.junit.platform.engine.discovery.DiscoverySelectors;
+import org.junit.platform.launcher.EngineFilter;
 import org.junit.platform.launcher.Launcher;
 import org.junit.platform.launcher.LauncherDiscoveryRequest;
 import org.junit.platform.launcher.TestExecutionListener;
 import org.junit.platform.launcher.TestPlan;
+import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder;
 import org.junit.platform.launcher.core.LauncherFactory;
 import org.junit.platform.launcher.listeners.SummaryGeneratingListener;
 import org.junit.platform.launcher.listeners.TestExecutionSummary;
@@ -67,23 +77,33 @@ import java.util.concurrent.TimeUnit;
  * <p>
  * This class is not thread-safe and isn't expected to be used for launching 
from
  * multiple different threads simultaneously.
+ * <p>This class is an internal implementation detail of the Ant project and 
although
+ * it's a public class, it isn't meant to be used outside of this project. 
This class
+ * can be changed, across releases, without any backward compatible guarantees 
and hence
+ * shouldn't be used or relied upon outside of this project.
  */
-class LauncherSupport {
+public class LauncherSupport {
 
     private final LaunchDefinition launchDefinition;
+    private final TestExecutionContext testExecutionContext;
 
     private boolean testsFailed;
 
     /**
      * Create a {@link LauncherSupport} for the passed {@link LaunchDefinition}
      *
-     * @param definition The launch definition which will be used for 
launching the tests
+     * @param definition           The launch definition which will be used 
for launching the tests
+     * @param testExecutionContext The {@link TestExecutionContext} to use for 
the tests
      */
-    LauncherSupport(final LaunchDefinition definition) {
+    public LauncherSupport(final LaunchDefinition definition, final 
TestExecutionContext testExecutionContext) {
         if (definition == null) {
             throw new IllegalArgumentException("Launch definition cannot be 
null");
         }
+        if (testExecutionContext == null) {
+            throw new IllegalArgumentException("Test execution context cannot 
be null");
+        }
         this.launchDefinition = definition;
+        this.testExecutionContext = testExecutionContext;
     }
 
     /**
@@ -93,7 +113,7 @@ class LauncherSupport {
      *                        an exception, or if any other exception occurred 
before or after launching
      *                        the tests
      */
-    void launch() throws BuildException {
+    public void launch() throws BuildException {
         final ClassLoader previousClassLoader = 
Thread.currentThread().getContextClassLoader();
         try {
             
Thread.currentThread().setContextClassLoader(this.launchDefinition.getClassLoader());
@@ -162,7 +182,14 @@ class LauncherSupport {
         }
         final List<TestRequest> requests = new ArrayList<>();
         for (final TestDefinition test : tests) {
-            final List<TestRequest> testRequests = test.createTestRequests();
+            final List<TestRequest> testRequests;
+            if (test instanceof SingleTestClass) {
+                testRequests = createTestRequests((SingleTestClass) test);
+            } else if (test instanceof TestClasses) {
+                testRequests = createTestRequests((TestClasses) test);
+            } else {
+                throw new BuildException("Unexpected test definition type " + 
test.getClass().getName());
+            }
             if (testRequests == null || testRequests.isEmpty()) {
                 continue;
             }
@@ -176,7 +203,7 @@ class LauncherSupport {
         final List<ListenerDefinition> applicableListenerElements = 
test.getListeners().isEmpty()
                 ? this.launchDefinition.getListeners() : test.getListeners();
         final List<TestExecutionListener> listeners = new ArrayList<>();
-        final Optional<Project> project = 
this.launchDefinition.getTestExecutionContext().getProject();
+        final Optional<Project> project = 
this.testExecutionContext.getProject();
         for (final ListenerDefinition applicableListener : 
applicableListenerElements) {
             if (project.isPresent() && 
!applicableListener.shouldUse(project.get())) {
                 log("Excluding listener " + applicableListener.getClassName() 
+ " since it's not applicable" +
@@ -198,7 +225,7 @@ class LauncherSupport {
 
         testRequest.closeUponCompletion(resultFormatter);
         // set the execution context
-        
resultFormatter.setContext(this.launchDefinition.getTestExecutionContext());
+        resultFormatter.setContext(this.testExecutionContext);
         // set the destination output stream for writing out the formatted 
result
         final java.nio.file.Path resultOutputFile = 
getListenerOutputFile(testRequest, formatterDefinition);
         try {
@@ -230,7 +257,7 @@ class LauncherSupport {
             return Paths.get(test.getOutputDir(), filename);
         }
         // neither listener nor the test define a output dir, so use basedir 
of the project
-        final TestExecutionContext testExecutionContext = 
this.launchDefinition.getTestExecutionContext();
+        final TestExecutionContext testExecutionContext = 
this.testExecutionContext;
         final String baseDir = 
testExecutionContext.getProperties().getProperty(MagicNames.PROJECT_BASEDIR);
         return Paths.get(baseDir, filename);
     }
@@ -270,7 +297,7 @@ class LauncherSupport {
             if (hasTestFailures && test.getFailureProperty() != null) {
                 // if there are test failures and the test is configured to 
set a property in case
                 // of failure, then set the property to true
-                final TestExecutionContext testExecutionContext = 
this.launchDefinition.getTestExecutionContext();
+                final TestExecutionContext testExecutionContext = 
this.testExecutionContext;
                 if (testExecutionContext.getProject().isPresent()) {
                     final Project project = 
testExecutionContext.getProject().get();
                     project.setNewProperty(test.getFailureProperty(), "true");
@@ -351,7 +378,7 @@ class LauncherSupport {
     }
 
     private void log(final String message, final Throwable t, final int level) 
{
-        final TestExecutionContext testExecutionContext = 
this.launchDefinition.getTestExecutionContext();
+        final TestExecutionContext testExecutionContext = 
this.testExecutionContext;
         if (testExecutionContext.getProject().isPresent()) {
             testExecutionContext.getProject().get().log(message, t, level);
             return;
@@ -364,6 +391,63 @@ class LauncherSupport {
         }
     }
 
+
+    private List<TestRequest> createTestRequests(final TestDefinition test) {
+        // create a TestRequest and add necessary selectors, filters to it
+        final LauncherDiscoveryRequestBuilder requestBuilder = 
LauncherDiscoveryRequestBuilder.request();
+        final TestRequest request = new TestRequest(test, requestBuilder);
+        addDiscoverySelectors(request);
+        addFilters(request);
+        return Collections.singletonList(request);
+    }
+
+    private void addDiscoverySelectors(final TestRequest testRequest) {
+        final TestDefinition test = testRequest.getOwner();
+        final LauncherDiscoveryRequestBuilder requestBuilder = 
testRequest.getDiscoveryRequest();
+        if (test instanceof SingleTestClass) {
+            final SingleTestClass singleTestClass = (SingleTestClass) test;
+            final String[] methods = singleTestClass.getMethods();
+            if (methods == null) {
+                
requestBuilder.selectors(DiscoverySelectors.selectClass(singleTestClass.getName()));
+            } else {
+                // add specific methods
+                for (final String method : methods) {
+                    
requestBuilder.selectors(DiscoverySelectors.selectMethod(singleTestClass.getName(),
 method));
+                }
+            }
+            return;
+        }
+        if (test instanceof TestClasses) {
+            final TestClasses testClasses = (TestClasses) test;
+            final List<String> testClassNames = 
testClasses.getTestClassNames();
+            if (testClassNames.isEmpty()) {
+                return;
+            }
+            for (final String testClass : testClassNames) {
+                
requestBuilder.selectors(DiscoverySelectors.selectClass(testClass));
+            }
+            return;
+        }
+    }
+
+    /**
+     * Add necessary {@link Filter JUnit filters} to the {@code testRequest}
+     *
+     * @param testRequest The test request
+     */
+    private void addFilters(final TestRequest testRequest) {
+        final LauncherDiscoveryRequestBuilder requestBuilder = 
testRequest.getDiscoveryRequest();
+        // add any engine filters
+        final String[] enginesToInclude = 
testRequest.getOwner().getIncludeEngines();
+        if (enginesToInclude != null && enginesToInclude.length > 0) {
+            
requestBuilder.filters(EngineFilter.includeEngines(enginesToInclude));
+        }
+        final String[] enginesToExclude = 
testRequest.getOwner().getExcludeEngines();
+        if (enginesToExclude != null && enginesToExclude.length > 0) {
+            
requestBuilder.filters(EngineFilter.excludeEngines(enginesToExclude));
+        }
+    }
+
     private enum StreamType {
         SYS_OUT,
         SYS_ERR

http://git-wip-us.apache.org/repos/asf/ant/blob/0cb9d22b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/ListenerDefinition.java
----------------------------------------------------------------------
diff --git 
a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/ListenerDefinition.java
 
b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/ListenerDefinition.java
deleted file mode 100644
index b2a3dba..0000000
--- 
a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/ListenerDefinition.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- */
-package org.apache.tools.ant.taskdefs.optional.junitlauncher;
-
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.PropertyHelper;
-import org.apache.tools.ant.types.EnumeratedAttribute;
-
-import javax.xml.stream.XMLStreamConstants;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamReader;
-import javax.xml.stream.XMLStreamWriter;
-
-import static 
org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ATTR_CLASS_NAME;
-import static 
org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ATTR_LISTENER_RESULT_FILE;
-import static 
org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ATTR_SEND_SYS_ERR;
-import static 
org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ATTR_SEND_SYS_OUT;
-import static 
org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ELM_LISTENER;
-
-/**
- * Represents the {@code &lt;listener&gt;} element within the {@code 
&lt;junitlauncher&gt;}
- * task
- */
-public class ListenerDefinition {
-
-
-    private static final String LEGACY_PLAIN = "legacy-plain";
-    private static final String LEGACY_BRIEF = "legacy-brief";
-    private static final String LEGACY_XML = "legacy-xml";
-
-    private String ifProperty;
-    private String unlessProperty;
-    private String className;
-    private String resultFile;
-    private boolean sendSysOut;
-    private boolean sendSysErr;
-    private String outputDir;
-
-    public ListenerDefinition() {
-
-    }
-
-    public void setClassName(final String className) {
-        this.className = className;
-    }
-
-    String getClassName() {
-        return this.className;
-    }
-
-    String getIfProperty() {
-        return ifProperty;
-    }
-
-    public void setIf(final String ifProperty) {
-        this.ifProperty = ifProperty;
-    }
-
-    String getUnlessProperty() {
-        return unlessProperty;
-    }
-
-    public void setUnless(final String unlessProperty) {
-        this.unlessProperty = unlessProperty;
-    }
-
-    public void setType(final ListenerType type) {
-        switch (type.getValue()) {
-            case LEGACY_PLAIN: {
-                
this.setClassName("org.apache.tools.ant.taskdefs.optional.junitlauncher.LegacyPlainResultFormatter");
-                break;
-            }
-            case LEGACY_BRIEF: {
-                
this.setClassName("org.apache.tools.ant.taskdefs.optional.junitlauncher.LegacyBriefResultFormatter");
-                break;
-            }
-            case LEGACY_XML: {
-                
this.setClassName("org.apache.tools.ant.taskdefs.optional.junitlauncher.LegacyXmlResultFormatter");
-                break;
-            }
-        }
-    }
-
-    public void setResultFile(final String filename) {
-        this.resultFile = filename;
-    }
-
-    String requireResultFile(final TestDefinition test) {
-        if (this.resultFile != null) {
-            return this.resultFile;
-        }
-        final StringBuilder sb = new StringBuilder("TEST-");
-        if (test instanceof NamedTest) {
-            sb.append(((NamedTest) test).getName());
-        } else {
-            sb.append("unknown");
-        }
-        sb.append(".");
-        final String suffix;
-        if 
("org.apache.tools.ant.taskdefs.optional.junitlauncher.LegacyXmlResultFormatter".equals(this.className))
 {
-            suffix = "xml";
-        } else {
-            suffix = "txt";
-        }
-        sb.append(suffix);
-        return sb.toString();
-    }
-
-    public void setSendSysOut(final boolean sendSysOut) {
-        this.sendSysOut = sendSysOut;
-    }
-
-    boolean shouldSendSysOut() {
-        return this.sendSysOut;
-    }
-
-    public void setSendSysErr(final boolean sendSysErr) {
-        this.sendSysErr = sendSysErr;
-    }
-
-    boolean shouldSendSysErr() {
-        return this.sendSysErr;
-    }
-
-    /**
-     * Sets the output directory for this listener
-     *
-     * @param dir Path to the output directory
-     * @since Ant 1.10.6
-     */
-    public void setOutputDir(final String dir) {
-        this.outputDir = dir;
-    }
-
-    String getOutputDir() {
-        return this.outputDir;
-    }
-
-    protected boolean shouldUse(final Project project) {
-        final PropertyHelper propertyHelper = 
PropertyHelper.getPropertyHelper(project);
-        return propertyHelper.testIfCondition(this.ifProperty) && 
propertyHelper.testUnlessCondition(this.unlessProperty);
-    }
-
-    public static class ListenerType extends EnumeratedAttribute {
-
-        @Override
-        public String[] getValues() {
-            return new String[]{LEGACY_PLAIN, LEGACY_BRIEF, LEGACY_XML};
-        }
-    }
-
-    void toForkedRepresentation(final XMLStreamWriter writer) throws 
XMLStreamException {
-        writer.writeStartElement(LD_XML_ELM_LISTENER);
-        writer.writeAttribute(LD_XML_ATTR_CLASS_NAME, this.className);
-        writer.writeAttribute(LD_XML_ATTR_SEND_SYS_ERR, 
Boolean.toString(this.sendSysErr));
-        writer.writeAttribute(LD_XML_ATTR_SEND_SYS_OUT, 
Boolean.toString(this.sendSysOut));
-        if (this.resultFile != null) {
-            writer.writeAttribute(LD_XML_ATTR_LISTENER_RESULT_FILE, 
this.resultFile);
-        }
-        writer.writeEndElement();
-    }
-
-    static ListenerDefinition fromForkedRepresentation(final XMLStreamReader 
reader) throws XMLStreamException {
-        reader.require(XMLStreamConstants.START_ELEMENT, null, 
LD_XML_ELM_LISTENER);
-        final ListenerDefinition listenerDef = new ListenerDefinition();
-        final String className = requireAttributeValue(reader, 
LD_XML_ATTR_CLASS_NAME);
-        listenerDef.setClassName(className);
-        final String sendSysErr = reader.getAttributeValue(null, 
LD_XML_ATTR_SEND_SYS_ERR);
-        if (sendSysErr != null) {
-            listenerDef.setSendSysErr(Boolean.parseBoolean(sendSysErr));
-        }
-        final String sendSysOut = reader.getAttributeValue(null, 
LD_XML_ATTR_SEND_SYS_OUT);
-        if (sendSysOut != null) {
-            listenerDef.setSendSysOut(Boolean.parseBoolean(sendSysOut));
-        }
-        final String resultFile = reader.getAttributeValue(null, 
LD_XML_ATTR_LISTENER_RESULT_FILE);
-        if (resultFile != null) {
-            listenerDef.setResultFile(resultFile);
-        }
-        reader.nextTag();
-        reader.require(XMLStreamConstants.END_ELEMENT, null, 
LD_XML_ELM_LISTENER);
-        return listenerDef;
-    }
-
-    private static String requireAttributeValue(final XMLStreamReader reader, 
final String attrName) throws XMLStreamException {
-        final String val = reader.getAttributeValue(null, attrName);
-        if (val != null) {
-            return val;
-        }
-        throw new XMLStreamException("Attribute " + attrName + " is missing at 
" + reader.getLocation());
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/ant/blob/0cb9d22b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/NamedTest.java
----------------------------------------------------------------------
diff --git 
a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/NamedTest.java 
b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/NamedTest.java
deleted file mode 100644
index 07039a6..0000000
--- 
a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/NamedTest.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- */
-package org.apache.tools.ant.taskdefs.optional.junitlauncher;
-
-/**
- * A test that has a name associated with it
- */
-public interface NamedTest {
-
-    /**
-     * @return Returns the name of the test
-     */
-    String getName();
-}

http://git-wip-us.apache.org/repos/asf/ant/blob/0cb9d22b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/SingleTestClass.java
----------------------------------------------------------------------
diff --git 
a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/SingleTestClass.java
 
b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/SingleTestClass.java
deleted file mode 100644
index 0321c48..0000000
--- 
a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/SingleTestClass.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- */
-package org.apache.tools.ant.taskdefs.optional.junitlauncher;
-
-import org.junit.platform.engine.discovery.DiscoverySelectors;
-import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder;
-
-import javax.xml.stream.XMLStreamConstants;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamReader;
-import javax.xml.stream.XMLStreamWriter;
-import java.util.Collections;
-import java.util.LinkedHashSet;
-import java.util.Set;
-import java.util.StringTokenizer;
-
-import static 
org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ATTR_CLASS_NAME;
-import static 
org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ATTR_EXCLUDE_ENGINES;
-import static 
org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ATTR_HALT_ON_FAILURE;
-import static 
org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ATTR_INCLUDE_ENGINES;
-import static 
org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ATTR_METHODS;
-import static 
org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ATTR_OUTPUT_DIRECTORY;
-import static 
org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ELM_TEST;
-
-/**
- * Represents the single {@code test} (class) that's configured to be launched 
by the {@link JUnitLauncherTask}
- */
-public class SingleTestClass extends TestDefinition implements NamedTest {
-
-    private String testClass;
-    private Set<String> testMethods;
-
-    public SingleTestClass() {
-
-    }
-
-    public void setName(final String test) {
-        if (test == null || test.trim().isEmpty()) {
-            throw new IllegalArgumentException("Test name cannot be null or 
empty string");
-        }
-        this.testClass = test;
-    }
-
-    public String getName() {
-        return this.testClass;
-    }
-
-    public void setMethods(final String methods) {
-        // parse the comma separated set of methods
-        if (methods == null || methods.trim().isEmpty()) {
-            this.testMethods = Collections.emptySet();
-            return;
-        }
-        final StringTokenizer tokenizer = new StringTokenizer(methods, ",");
-        if (!tokenizer.hasMoreTokens()) {
-            this.testMethods = Collections.emptySet();
-            return;
-        }
-        // maintain specified ordering
-        this.testMethods = new LinkedHashSet<>();
-        while (tokenizer.hasMoreTokens()) {
-            final String method = tokenizer.nextToken().trim();
-            if (method.isEmpty()) {
-                continue;
-            }
-            this.testMethods.add(method);
-        }
-    }
-
-    boolean hasMethodsSpecified() {
-        return this.testMethods != null && !this.testMethods.isEmpty();
-    }
-
-    String[] getMethods() {
-        if (!hasMethodsSpecified()) {
-            return null;
-        }
-        return this.testMethods.toArray(new String[this.testMethods.size()]);
-    }
-
-    @Override
-    void addDiscoverySelectors(final TestRequest testRequest) {
-        final LauncherDiscoveryRequestBuilder requestBuilder = 
testRequest.getDiscoveryRequest();
-        if (!this.hasMethodsSpecified()) {
-            
requestBuilder.selectors(DiscoverySelectors.selectClass(this.testClass));
-        } else {
-            // add specific methods
-            for (final String method : this.getMethods()) {
-                
requestBuilder.selectors(DiscoverySelectors.selectMethod(this.testClass, 
method));
-            }
-        }
-    }
-
-
-    @Override
-    protected void toForkedRepresentation(final JUnitLauncherTask task, final 
XMLStreamWriter writer) throws XMLStreamException {
-        writer.writeStartElement(LD_XML_ELM_TEST);
-        writer.writeAttribute(LD_XML_ATTR_CLASS_NAME, testClass);
-        if (testMethods != null) {
-            final StringBuilder sb = new StringBuilder();
-            for (final String method : testMethods) {
-                if (sb.length() != 0) {
-                    sb.append(",");
-                }
-                sb.append(method);
-            }
-            writer.writeAttribute(LD_XML_ATTR_METHODS, sb.toString());
-        }
-        if (haltOnFailure != null) {
-            writer.writeAttribute(LD_XML_ATTR_HALT_ON_FAILURE, 
haltOnFailure.toString());
-        }
-        if (outputDir != null) {
-            writer.writeAttribute(LD_XML_ATTR_OUTPUT_DIRECTORY, outputDir);
-        }
-        if (includeEngines != null) {
-            writer.writeAttribute(LD_XML_ATTR_INCLUDE_ENGINES, includeEngines);
-        }
-        if (excludeEngines != null) {
-            writer.writeAttribute(LD_XML_ATTR_EXCLUDE_ENGINES, excludeEngines);
-        }
-        // listeners for this test
-        if (listeners != null) {
-            for (final ListenerDefinition listenerDef : getListeners()) {
-                if (!listenerDef.shouldUse(task.getProject())) {
-                    // not applicable
-                    continue;
-                }
-                listenerDef.toForkedRepresentation(writer);
-            }
-        }
-        writer.writeEndElement();
-    }
-
-    static TestDefinition fromForkedRepresentation(final XMLStreamReader 
reader) throws XMLStreamException {
-        reader.require(XMLStreamConstants.START_ELEMENT, null, 
LD_XML_ELM_TEST);
-        final SingleTestClass testDefinition = new SingleTestClass();
-        final String testClassName = requireAttributeValue(reader, 
LD_XML_ATTR_CLASS_NAME);
-        testDefinition.setName(testClassName);
-        final String methodNames = reader.getAttributeValue(null, 
LD_XML_ATTR_METHODS);
-        if (methodNames != null) {
-            testDefinition.setMethods(methodNames);
-        }
-        final String halt = reader.getAttributeValue(null, 
LD_XML_ATTR_HALT_ON_FAILURE);
-        if (halt != null) {
-            testDefinition.setHaltOnFailure(Boolean.parseBoolean(halt));
-        }
-        final String outDir = reader.getAttributeValue(null, 
LD_XML_ATTR_OUTPUT_DIRECTORY);
-        if (outDir != null) {
-            testDefinition.setOutputDir(outDir);
-        }
-        final String includeEngs = reader.getAttributeValue(null, 
LD_XML_ATTR_INCLUDE_ENGINES);
-        if (includeEngs != null) {
-            testDefinition.setIncludeEngines(includeEngs);
-        }
-        final String excludeEngs = reader.getAttributeValue(null, 
LD_XML_ATTR_EXCLUDE_ENGINES);
-        if (excludeEngs != null) {
-            testDefinition.setExcludeEngines(excludeEngs);
-        }
-        while (reader.nextTag() != XMLStreamConstants.END_ELEMENT) {
-            reader.require(XMLStreamConstants.START_ELEMENT, null, 
Constants.LD_XML_ELM_LISTENER);
-            
testDefinition.addConfiguredListener(ListenerDefinition.fromForkedRepresentation(reader));
-        }
-        return testDefinition;
-    }
-
-    private static String requireAttributeValue(final XMLStreamReader reader, 
final String attrName) throws XMLStreamException {
-        final String val = reader.getAttributeValue(null, attrName);
-        if (val != null) {
-            return val;
-        }
-        throw new XMLStreamException("Attribute " + attrName + " is missing at 
" + reader.getLocation());
-    }
-}

http://git-wip-us.apache.org/repos/asf/ant/blob/0cb9d22b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/StandaloneLauncher.java
----------------------------------------------------------------------
diff --git 
a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/StandaloneLauncher.java
 
b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/StandaloneLauncher.java
index 69a1556..eb6e064 100644
--- 
a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/StandaloneLauncher.java
+++ 
b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/StandaloneLauncher.java
@@ -20,6 +20,13 @@ package org.apache.tools.ant.taskdefs.optional.junitlauncher;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.optional.junitlauncher.confined.Constants;
+import 
org.apache.tools.ant.taskdefs.optional.junitlauncher.confined.JUnitLauncherTask;
+import 
org.apache.tools.ant.taskdefs.optional.junitlauncher.confined.LaunchDefinition;
+import 
org.apache.tools.ant.taskdefs.optional.junitlauncher.confined.ListenerDefinition;
+import 
org.apache.tools.ant.taskdefs.optional.junitlauncher.confined.SingleTestClass;
+import 
org.apache.tools.ant.taskdefs.optional.junitlauncher.confined.TestClasses;
+import 
org.apache.tools.ant.taskdefs.optional.junitlauncher.confined.TestDefinition;
 
 import javax.xml.stream.XMLInputFactory;
 import javax.xml.stream.XMLStreamReader;
@@ -37,12 +44,12 @@ import static 
javax.xml.stream.XMLStreamConstants.END_DOCUMENT;
 import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
 import static javax.xml.stream.XMLStreamConstants.START_DOCUMENT;
 import static javax.xml.stream.XMLStreamConstants.START_ELEMENT;
-import static 
org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ATTR_HALT_ON_FAILURE;
-import static 
org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ATTR_PRINT_SUMMARY;
-import static 
org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ELM_LAUNCH_DEF;
-import static 
org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ELM_LISTENER;
-import static 
org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ELM_TEST;
-import static 
org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ELM_TEST_CLASSES;
+import static 
org.apache.tools.ant.taskdefs.optional.junitlauncher.confined.Constants.LD_XML_ATTR_HALT_ON_FAILURE;
+import static 
org.apache.tools.ant.taskdefs.optional.junitlauncher.confined.Constants.LD_XML_ATTR_PRINT_SUMMARY;
+import static 
org.apache.tools.ant.taskdefs.optional.junitlauncher.confined.Constants.LD_XML_ELM_LAUNCH_DEF;
+import static 
org.apache.tools.ant.taskdefs.optional.junitlauncher.confined.Constants.LD_XML_ELM_LISTENER;
+import static 
org.apache.tools.ant.taskdefs.optional.junitlauncher.confined.Constants.LD_XML_ELM_TEST;
+import static 
org.apache.tools.ant.taskdefs.optional.junitlauncher.confined.Constants.LD_XML_ELM_TEST_CLASSES;
 
 /**
  * Used for launching forked tests from the {@link JUnitLauncherTask}.
@@ -98,8 +105,7 @@ public class StandaloneLauncher {
                 i = i + numArgsConsumed;
             }
 
-            launchDefinition.setTestExecutionContext(forkedExecution);
-            final LauncherSupport launcherSupport = new 
LauncherSupport(launchDefinition);
+            final LauncherSupport launcherSupport = new 
LauncherSupport(launchDefinition, forkedExecution);
             try {
                 launcherSupport.launch();
             } catch (Throwable t) {
@@ -240,19 +246,9 @@ public class StandaloneLauncher {
             return this;
         }
 
-        public ForkedLaunch setTestExecutionContext(final TestExecutionContext 
testExecutionContext) {
-            this.testExecutionContext = testExecutionContext;
-            return this;
-        }
-
         @Override
         public ClassLoader getClassLoader() {
             return this.getClass().getClassLoader();
         }
-
-        @Override
-        public TestExecutionContext getTestExecutionContext() {
-            return this.testExecutionContext;
-        }
     }
 }

http://git-wip-us.apache.org/repos/asf/ant/blob/0cb9d22b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/TestClasses.java
----------------------------------------------------------------------
diff --git 
a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/TestClasses.java
 
b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/TestClasses.java
deleted file mode 100644
index 1769d10..0000000
--- 
a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/TestClasses.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- */
-package org.apache.tools.ant.taskdefs.optional.junitlauncher;
-
-import org.apache.tools.ant.types.Resource;
-import org.apache.tools.ant.types.ResourceCollection;
-import org.apache.tools.ant.types.resources.Resources;
-import org.apache.tools.ant.types.resources.StringResource;
-import org.junit.platform.engine.discovery.DiscoverySelectors;
-import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder;
-
-import javax.xml.stream.XMLStreamConstants;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamReader;
-import javax.xml.stream.XMLStreamWriter;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import static 
org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ATTR_CLASS_NAME;
-import static 
org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ATTR_EXCLUDE_ENGINES;
-import static 
org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ATTR_HALT_ON_FAILURE;
-import static 
org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ATTR_INCLUDE_ENGINES;
-import static 
org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ATTR_OUTPUT_DIRECTORY;
-import static 
org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ELM_TEST;
-import static 
org.apache.tools.ant.taskdefs.optional.junitlauncher.Constants.LD_XML_ELM_TEST_CLASSES;
-
-/**
- * Represents a {@code testclasses} that's configured to be launched by the 
{@link JUnitLauncherTask}
- */
-public class TestClasses extends TestDefinition {
-
-    private final Resources resources = new Resources();
-
-    public TestClasses() {
-
-    }
-
-    public void add(final ResourceCollection resourceCollection) {
-        this.resources.add(resourceCollection);
-    }
-
-    @Override
-    void addDiscoverySelectors(final TestRequest testRequest) {
-        final List<String> tests = getTestClassNames();
-        if (tests.isEmpty()) {
-            return;
-        }
-        final LauncherDiscoveryRequestBuilder requestBuilder = 
testRequest.getDiscoveryRequest();
-        for (final String test : tests) {
-            requestBuilder.selectors(DiscoverySelectors.selectClass(test));
-        }
-    }
-
-    private List<String> getTestClassNames() {
-        if (this.resources.isEmpty()) {
-            return Collections.emptyList();
-        }
-        final List<String> tests = new ArrayList<>();
-        for (final Resource resource : resources) {
-            if (!resource.isExists()) {
-                continue;
-            }
-            final String name = resource.getName();
-            // we only consider .class files
-            if (!name.endsWith(".class")) {
-                continue;
-            }
-            final String className = name.substring(0, name.lastIndexOf('.'));
-            tests.add(className.replace(File.separatorChar, '.').replace('/', 
'.').replace('\\', '.'));
-        }
-        return tests;
-    }
-
-    @Override
-    protected void toForkedRepresentation(final JUnitLauncherTask task, final 
XMLStreamWriter writer) throws XMLStreamException {
-        writer.writeStartElement(LD_XML_ELM_TEST_CLASSES);
-        // write out each test class
-        for (final String test : getTestClassNames()) {
-            writer.writeStartElement(LD_XML_ELM_TEST);
-            writer.writeAttribute(LD_XML_ATTR_CLASS_NAME, test);
-            if (haltOnFailure != null) {
-                writer.writeAttribute(LD_XML_ATTR_HALT_ON_FAILURE, 
haltOnFailure.toString());
-            }
-            if (outputDir != null) {
-                writer.writeAttribute(LD_XML_ATTR_OUTPUT_DIRECTORY, outputDir);
-            }
-            if (includeEngines != null) {
-                writer.writeAttribute(LD_XML_ATTR_INCLUDE_ENGINES, 
includeEngines);
-            }
-            if (excludeEngines != null) {
-                writer.writeAttribute(LD_XML_ATTR_EXCLUDE_ENGINES, 
excludeEngines);
-            }
-            // listeners for this test
-            if (listeners != null) {
-                for (final ListenerDefinition listenerDef : getListeners()) {
-                    if (!listenerDef.shouldUse(task.getProject())) {
-                        // not applicable
-                        continue;
-                    }
-                    listenerDef.toForkedRepresentation(writer);
-                }
-            }
-            writer.writeEndElement();
-        }
-        writer.writeEndElement();
-    }
-
-    static List<TestDefinition> fromForkedRepresentation(final XMLStreamReader 
reader) throws XMLStreamException {
-        reader.require(XMLStreamConstants.START_ELEMENT, null, 
LD_XML_ELM_TEST_CLASSES);
-        final TestClasses testDefinition = new TestClasses();
-        // read out as multiple SingleTestClass representations
-        while (reader.nextTag() != XMLStreamConstants.END_ELEMENT) {
-            reader.require(XMLStreamConstants.START_ELEMENT, null, 
Constants.LD_XML_ELM_TEST);
-            final String testClassName = requireAttributeValue(reader, 
LD_XML_ATTR_CLASS_NAME);
-            testDefinition.add(new StringResource(testClassName + ".class"));
-            final String halt = reader.getAttributeValue(null, 
LD_XML_ATTR_HALT_ON_FAILURE);
-            if (halt != null) {
-                testDefinition.setHaltOnFailure(Boolean.parseBoolean(halt));
-            }
-            final String outDir = reader.getAttributeValue(null, 
LD_XML_ATTR_OUTPUT_DIRECTORY);
-            if (outDir != null) {
-                testDefinition.setOutputDir(outDir);
-            }
-            final String includeEngs = reader.getAttributeValue(null, 
LD_XML_ATTR_INCLUDE_ENGINES);
-            if (includeEngs != null) {
-                testDefinition.setIncludeEngines(includeEngs);
-            }
-            final String excludeEngs = reader.getAttributeValue(null, 
LD_XML_ATTR_EXCLUDE_ENGINES);
-            if (excludeEngs != null) {
-                testDefinition.setExcludeEngines(excludeEngs);
-            }
-            while (reader.nextTag() != XMLStreamConstants.END_ELEMENT) {
-                reader.require(XMLStreamConstants.START_ELEMENT, null, 
Constants.LD_XML_ELM_LISTENER);
-                
testDefinition.addConfiguredListener(ListenerDefinition.fromForkedRepresentation(reader));
-            }
-            reader.require(XMLStreamConstants.END_ELEMENT, null, 
Constants.LD_XML_ELM_TEST);
-        }
-        reader.require(XMLStreamConstants.END_ELEMENT, null, 
LD_XML_ELM_TEST_CLASSES);
-        return Collections.singletonList(testDefinition);
-    }
-
-    private static String requireAttributeValue(final XMLStreamReader reader, 
final String attrName) throws XMLStreamException {
-        final String val = reader.getAttributeValue(null, attrName);
-        if (val != null) {
-            return val;
-        }
-        throw new XMLStreamException("Attribute " + attrName + " is missing at 
" + reader.getLocation());
-    }
-}

http://git-wip-us.apache.org/repos/asf/ant/blob/0cb9d22b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/TestDefinition.java
----------------------------------------------------------------------
diff --git 
a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/TestDefinition.java
 
b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/TestDefinition.java
deleted file mode 100644
index 4a42b6a..0000000
--- 
a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/TestDefinition.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- */
-package org.apache.tools.ant.taskdefs.optional.junitlauncher;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.PropertyHelper;
-import org.junit.platform.engine.Filter;
-import org.junit.platform.launcher.EngineFilter;
-import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder;
-
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamWriter;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Represents the configuration details of a test that needs to be launched by 
the {@link JUnitLauncherTask}
- */
-abstract class TestDefinition {
-
-    protected String ifProperty;
-    protected String unlessProperty;
-    protected Boolean haltOnFailure;
-    protected String failureProperty;
-    protected String outputDir;
-    protected String includeEngines;
-    protected String excludeEngines;
-    protected ForkDefinition forkDefinition;
-
-    protected List<ListenerDefinition> listeners = new ArrayList<>();
-
-    String getIfProperty() {
-        return ifProperty;
-    }
-
-    public void setIf(final String ifProperty) {
-        this.ifProperty = ifProperty;
-    }
-
-    String getUnlessProperty() {
-        return unlessProperty;
-    }
-
-    public void setUnless(final String unlessProperty) {
-        this.unlessProperty = unlessProperty;
-    }
-
-    boolean isHaltOnFailure() {
-        return this.haltOnFailure != null && this.haltOnFailure;
-    }
-
-    Boolean getHaltOnFailure() {
-        return this.haltOnFailure;
-    }
-
-    public void setHaltOnFailure(final boolean haltonfailure) {
-        this.haltOnFailure = haltonfailure;
-    }
-
-    String getFailureProperty() {
-        return failureProperty;
-    }
-
-    public void setFailureProperty(final String failureProperty) {
-        this.failureProperty = failureProperty;
-    }
-
-    public void addConfiguredListener(final ListenerDefinition listener) {
-        this.listeners.add(listener);
-    }
-
-    List<ListenerDefinition> getListeners() {
-        return Collections.unmodifiableList(this.listeners);
-    }
-
-    public void setOutputDir(final String dir) {
-        this.outputDir = dir;
-    }
-
-    String getOutputDir() {
-        return this.outputDir;
-    }
-
-    public ForkDefinition createFork() {
-        if (this.forkDefinition != null) {
-            throw new BuildException("Test definition cannot have more than 
one fork elements");
-        }
-        this.forkDefinition = new ForkDefinition();
-        return this.forkDefinition;
-    }
-
-    ForkDefinition getForkDefinition() {
-        return this.forkDefinition;
-    }
-
-    /**
-     * Create and return the {@link TestRequest TestRequests} for this test 
definition. This
-     * typically involves creating the JUnit test discovery request(s) and 
applying the necessary
-     * discovery selectors, filters and other necessary constructs.
-     *
-     * @return Returns the test requests
-     */
-    List<TestRequest> createTestRequests() {
-        // create a TestRequest and add necessary selectors, filters to it
-        final LauncherDiscoveryRequestBuilder requestBuilder = 
LauncherDiscoveryRequestBuilder.request();
-        final TestRequest request = new TestRequest(this, requestBuilder);
-        addDiscoverySelectors(request);
-        addFilters(request);
-        return Collections.singletonList(request);
-    }
-
-    /**
-     * Add necessary {@link org.junit.platform.engine.DiscoverySelector JUnit 
discovery selectors} to
-     * the {@code testRequest}
-     *
-     * @param testRequest The test request
-     */
-    abstract void addDiscoverySelectors(final TestRequest testRequest);
-
-    /**
-     * Add necessary {@link Filter JUnit filters} to the {@code testRequest}
-     *
-     * @param testRequest The test request
-     */
-    void addFilters(final TestRequest testRequest) {
-        final LauncherDiscoveryRequestBuilder requestBuilder = 
testRequest.getDiscoveryRequest();
-        // add any engine filters
-        final String[] enginesToInclude = this.getIncludeEngines();
-        if (enginesToInclude != null && enginesToInclude.length > 0) {
-            
requestBuilder.filters(EngineFilter.includeEngines(enginesToInclude));
-        }
-        final String[] enginesToExclude = this.getExcludeEngines();
-        if (enginesToExclude != null && enginesToExclude.length > 0) {
-            
requestBuilder.filters(EngineFilter.excludeEngines(enginesToExclude));
-        }
-    }
-
-    protected boolean shouldRun(final Project project) {
-        final PropertyHelper propertyHelper = 
PropertyHelper.getPropertyHelper(project);
-        return propertyHelper.testIfCondition(this.ifProperty) && 
propertyHelper.testUnlessCondition(this.unlessProperty);
-    }
-
-    String[] getIncludeEngines() {
-        return includeEngines == null ? new String[0] : 
split(this.includeEngines, ",");
-    }
-
-    public void setIncludeEngines(final String includeEngines) {
-        this.includeEngines = includeEngines;
-    }
-
-    String[] getExcludeEngines() {
-        return excludeEngines == null ? new String[0] : 
split(this.excludeEngines, ",");
-    }
-
-    public void setExcludeEngines(final String excludeEngines) {
-        this.excludeEngines = excludeEngines;
-    }
-
-    private static String[] split(final String value, final String delimiter) {
-        if (value == null) {
-            return new String[0];
-        }
-        final List<String> parts = new ArrayList<>();
-        for (final String part : value.split(delimiter)) {
-            if (part.trim().isEmpty()) {
-                // skip it
-                continue;
-            }
-            parts.add(part);
-        }
-        return parts.toArray(new String[parts.size()]);
-    }
-
-    protected abstract void toForkedRepresentation(JUnitLauncherTask task, 
XMLStreamWriter writer) throws XMLStreamException;
-
-}

http://git-wip-us.apache.org/repos/asf/ant/blob/0cb9d22b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/TestExecutionContext.java
----------------------------------------------------------------------
diff --git 
a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/TestExecutionContext.java
 
b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/TestExecutionContext.java
index 5e5b608..207c144 100644
--- 
a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/TestExecutionContext.java
+++ 
b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/TestExecutionContext.java
@@ -18,6 +18,7 @@
 package org.apache.tools.ant.taskdefs.optional.junitlauncher;
 
 import org.apache.tools.ant.Project;
+import 
org.apache.tools.ant.taskdefs.optional.junitlauncher.confined.JUnitLauncherTask;
 
 import java.util.Optional;
 import java.util.Properties;

http://git-wip-us.apache.org/repos/asf/ant/blob/0cb9d22b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/TestRequest.java
----------------------------------------------------------------------
diff --git 
a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/TestRequest.java
 
b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/TestRequest.java
index 0f2f677..ef15536 100644
--- 
a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/TestRequest.java
+++ 
b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/TestRequest.java
@@ -17,6 +17,8 @@
  */
 package org.apache.tools.ant.taskdefs.optional.junitlauncher;
 
+import 
org.apache.tools.ant.taskdefs.optional.junitlauncher.confined.JUnitLauncherTask;
+import 
org.apache.tools.ant.taskdefs.optional.junitlauncher.confined.TestDefinition;
 import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder;
 
 import java.io.Closeable;

http://git-wip-us.apache.org/repos/asf/ant/blob/0cb9d22b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/confined/Constants.java
----------------------------------------------------------------------
diff --git 
a/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/confined/Constants.java
 
b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/confined/Constants.java
new file mode 100644
index 0000000..53bc0dc
--- /dev/null
+++ 
b/src/main/org/apache/tools/ant/taskdefs/optional/junitlauncher/confined/Constants.java
@@ -0,0 +1,54 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs.optional.junitlauncher.confined;
+
+/**
+ * Constants used within the junitlauncher task
+ */
+public final class Constants {
+
+    public static final int FORK_EXIT_CODE_SUCCESS = 0;
+    public static final int FORK_EXIT_CODE_EXCEPTION = 1;
+    public static final int FORK_EXIT_CODE_TESTS_FAILED = 2;
+    public static final int FORK_EXIT_CODE_TIMED_OUT = 3;
+
+    public static final String ARG_PROPERTIES = "--properties";
+    public static final String ARG_LAUNCH_DEFINITION = "--launch-definition";
+
+
+    public static final String LD_XML_ELM_LAUNCH_DEF = "launch-definition";
+    public static final String LD_XML_ELM_TEST = "test";
+    public static final String LD_XML_ELM_TEST_CLASSES = "test-classes";
+    public static final String LD_XML_ATTR_HALT_ON_FAILURE = "haltOnFailure";
+    public static final String LD_XML_ATTR_OUTPUT_DIRECTORY = "outDir";
+    public static final String LD_XML_ATTR_INCLUDE_ENGINES = "includeEngines";
+    public static final String LD_XML_ATTR_EXCLUDE_ENGINES = "excludeEngines";
+    public static final String LD_XML_ATTR_CLASS_NAME = "classname";
+    public static final String LD_XML_ATTR_METHODS = "methods";
+    public static final String LD_XML_ATTR_PRINT_SUMMARY = "printSummary";
+    public static final String LD_XML_ELM_LISTENER = "listener";
+    public static final String LD_XML_ATTR_SEND_SYS_ERR = "sendSysErr";
+    public static final String LD_XML_ATTR_SEND_SYS_OUT = "sendSysOut";
+    public static final String LD_XML_ATTR_LISTENER_RESULT_FILE = "resultFile";
+
+
+    private Constants() {
+
+    }
+}

Reply via email to