private TestResultHolder executeAsForked()

in src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java [1151:1317]


    private TestResultHolder executeAsForked(JUnitTest test,
                                             final ExecuteWatchdog watchdog,
                                             final File casesFile)
        throws BuildException {

        if (perm != null) {
            log("Permissions ignored when running in forked mode!",
                Project.MSG_WARN);
        }

        CommandlineJava cmd;
        try {
            cmd = (CommandlineJava) getCommandline().clone();
        } catch (final CloneNotSupportedException e) {
            throw new BuildException("This shouldn't happen", e, getLocation());
        }
        if (casesFile == null) {
            cmd.createArgument().setValue(test.getName());
            if (test.getMethods() != null) {
                cmd.createArgument().setValue(Constants.METHOD_NAMES + test.getMethodsString());
            }
        } else {
            log("Running multiple tests in the same VM", Project.MSG_VERBOSE);
            cmd.createArgument().setValue(Constants.TESTSFILE + casesFile);
        }

        cmd.createArgument().setValue(Constants.SKIP_NON_TESTS + test.isSkipNonTests());
        cmd.createArgument().setValue(Constants.FILTERTRACE + test.getFiltertrace());
        cmd.createArgument().setValue(Constants.HALT_ON_ERROR + test.getHaltonerror());
        cmd.createArgument().setValue(Constants.HALT_ON_FAILURE
                                      + test.getHaltonfailure());
        checkIncludeAntRuntime(cmd);

        checkIncludeSummary(cmd);

        cmd.createArgument().setValue(Constants.SHOWOUTPUT
                                      + showOutput);
        cmd.createArgument().setValue(Constants.OUTPUT_TO_FORMATTERS
                                      + outputToFormatters);
        cmd.createArgument().setValue(Constants.LOG_FAILED_TESTS
                                      + logFailedTests);
        cmd.createArgument().setValue(Constants.THREADID
                                      + test.getThread());

        // #31885
        cmd.createArgument().setValue(Constants.LOGTESTLISTENEREVENTS
                                      + getEnableTestListenerEvents());

        StringBuilder formatterArg = new StringBuilder(STRING_BUFFER_SIZE);
        final FormatterElement[] feArray = mergeFormatters(test);
        for (final FormatterElement fe : feArray) {
            if (fe.shouldUse(this)) {
                formatterArg.append(Constants.FORMATTER);
                formatterArg.append(fe.getClassname());
                final File outFile = getOutput(fe, test);
                if (outFile != null) {
                    formatterArg.append(",");
                    formatterArg.append(outFile);
                }
                cmd.createArgument().setValue(formatterArg.toString());
                formatterArg = new StringBuilder();
            }
        }

        final File vmWatcher = createTempPropertiesFile("junitvmwatcher");
        cmd.createArgument().setValue(Constants.CRASHFILE
                                      + vmWatcher.getAbsolutePath());
        final File propsFile = createTempPropertiesFile("junit");
        cmd.createArgument().setValue(Constants.PROPSFILE
                                      + propsFile.getAbsolutePath());
        final Hashtable<String, Object> p = getProject().getProperties();
        final Properties props = new Properties();
        props.putAll(p);
        try {
            final OutputStream outstream = Files.newOutputStream(propsFile.toPath());
            props.store(outstream, "Ant JUnitTask generated properties file");
            outstream.close();
        } catch (final IOException e) {
            FILE_UTILS.tryHardToDelete(propsFile);
            throw new BuildException("Error creating temporary properties "
                                     + "file.", e, getLocation());
        }

        final Execute execute = new Execute(
            new JUnitLogStreamHandler(
                this,
                Project.MSG_INFO,
                Project.MSG_WARN),
            watchdog);
        execute.setCommandline(cmd.getCommandline());
        execute.setAntRun(getProject());
        if (dir != null) {
            execute.setWorkingDirectory(dir);
        }

        final String[] environment = env.getVariables();
        if (environment != null) {
            for (String variable : environment) {
                log("Setting environment variable: " + variable,
                        Project.MSG_VERBOSE);
            }
        }
        execute.setNewenvironment(newEnvironment);
        execute.setEnvironment(environment);

        log(cmd.describeCommand(), Project.MSG_VERBOSE);

        checkForkedPath(cmd);

        final TestResultHolder result = new TestResultHolder();
        boolean success = false;
        try {
            result.exitCode = execute.execute();
            success = true;
        } catch (final IOException e) {
            throw new BuildException("Process fork failed.", e, getLocation());
        } finally {
            String vmCrashString = "unknown";
            BufferedReader br = null;
            try {
                if (vmWatcher.exists()) {
                    br = new BufferedReader(new FileReader(vmWatcher));
                    vmCrashString = br.readLine();
                } else {
                    vmCrashString = "Monitor file ("
                            + vmWatcher.getAbsolutePath()
                            + ") missing, location not writable,"
                            + " testcase not started or mixing ant versions?";
                }
            } catch (final Exception e) {
                log(StringUtils.getStackTrace(e), Project.MSG_INFO);
                // ignored.
            } finally {
                FileUtils.close(br);
                if (vmWatcher.exists()) {
                    FILE_UTILS.tryHardToDelete(vmWatcher);
                }
            }

            final boolean crash = (watchdog != null && watchdog.killedProcess())
                || !Constants.TERMINATED_SUCCESSFULLY.equals(vmCrashString);

            if (casesFile != null && crash) {
                test = createDummyTestForBatchTest(test);
            }

            if (watchdog != null && watchdog.killedProcess()) {
                result.timedOut = true;
                logTimeout(feArray, test, vmCrashString);
            } else if (crash) {
                result.crashed = true;
                logVmCrash(feArray, test, vmCrashString);
            }

            if (!FILE_UTILS.tryHardToDelete(propsFile)) {
                String msg = "Could not delete temporary properties file '"
                    + propsFile.getAbsolutePath() + "'.";
                if (success) {
                    throw new BuildException(msg); //NOSONAR
                }
                // don't hide inner exception
                log(msg, Project.MSG_ERR);
            }
        }

        return result;
    }