Browse Source

#38799: <junit> task should work so long as junit.jar

present in <classpath> even if not among Ant libs.


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@381467 13f79535-47bb-0310-9956-ffa450edef68
master
Jesse N. Glick 19 years ago
parent
commit
9af46a2ca0
12 changed files with 351 additions and 88 deletions
  1. +3
    -1
      WHATSNEW
  2. +20
    -9
      docs/manual/OptionalTasks/junit.html
  3. +2
    -2
      docs/manual/install.html
  4. +5
    -1
      src/main/org/apache/tools/ant/AntClassLoader.java
  5. +8
    -7
      src/main/org/apache/tools/ant/taskdefs/optional/junit/FormatterElement.java
  6. +2
    -2
      src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitResultFormatter.java
  7. +111
    -32
      src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java
  8. +110
    -0
      src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskMirror.java
  9. +72
    -0
      src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskMirrorImpl.java
  10. +12
    -32
      src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java
  11. +1
    -1
      src/main/org/apache/tools/ant/taskdefs/optional/junit/SummaryJUnitResultFormatter.java
  12. +5
    -1
      xdocs/faq.xml

+ 3
- 1
WHATSNEW View File

@@ -1,4 +1,4 @@
Changes from current Ant 1.6.5 version to current RCS version
Changes from current Ant 1.6.5 version to current SVN version
=============================================================

Changes that could break older environments:
@@ -77,6 +77,8 @@ Changes that could break older environments:
Fixed bugs:
-----------

* <junit> can now work with junit.jar in its <classpath>. Bugzilla Report 38799.

* Some potential NullPointerExceptions, Bugzilla Reports 37765 and 38056

* Problem when adding multiple filter files, Bugzilla Report 37341


+ 20
- 9
docs/manual/OptionalTasks/junit.html View File

@@ -19,12 +19,12 @@ Library Dependencies</a> for more information.
</p>
<p>
<strong>Note</strong>:
You must have <code>junit.jar</code> and the class files for the
<code>&lt;junit&gt;</code> task in the same classpath.
You must have <code>junit.jar</code> available.
You can do one of:
</p>
<ol>
<li>
Put both <code>junit.jar</code> and the optional tasks jar file in
Put both <code>junit.jar</code> and <code>ant-junit.jar</code> in
<code>ANT_HOME/lib</code>.
</li>
<li>
@@ -32,15 +32,23 @@ Do not put either in <code>ANT_HOME/lib</code>, and instead
include their locations in your <code>CLASSPATH</code> environment variable.
</li>
<li>
Do neither of the above, and instead, specify their locations using
a <code>&lt;classpath&gt;</code> element in the build file.

Add both JARs to your classpath using <code>-lib</code>.
</li>
<li>
Specify the locations of both JARs using
a <code>&lt;classpath&gt;</code> element in a <code>&lt;taskdef&gt;</code> in the build file.
</li>
<li>
Leave <code>ant-junit.jar</code> in its default location in <code>ANT_HOME/lib</code>
but include <code>junit.jar</code> in the <code>&lt;classpath&gt;</code> passed
to <code>&lt;junit&gt;</code>. <em>(since Ant 1.7)</em>
</li>
</ol>
<p>
See <a href="../../faq.html#delegating-classloader" target="_top">the
FAQ</a> for details.
</ol>
</p>


<p>Tests are defined by nested <code>test</code> or
<code>batchtest</code> tags (see <a href="#nested">nested
elements</a>).</p>
@@ -217,6 +225,9 @@ supports a nested <code>&lt;classpath&gt;</code>
element that represents a <a href="../using.html#path">PATH like
structure</a>.</p>

<p>As of Ant 1.7, this classpath may be used to refer to <code>junit.jar</code>
as well as your tests and the tested code.

<h4>jvmarg</h4>

<p>If <code>fork</code> is enabled, additional parameters may be passed to
@@ -580,7 +591,7 @@ aborted. Results are collected in files named
<code>${reports.tests}</code>.</p>

<hr>
<p align="center">Copyright &copy; 2000-2005 The Apache Software Foundation. All rights
<p align="center">Copyright &copy; 2000-2006 The Apache Software Foundation. All rights
Reserved.</p>
</body>
</html>

+ 2
- 2
docs/manual/install.html View File

@@ -456,7 +456,7 @@ you need jakarta-oro 2.0.1 or later, and <a href="#commons-net">commons-net</a><
</tr>
<tr>
<td>junit.jar</td>
<td>junit tasks</td>
<td><code>&lt;junit&gt;</code> task. May be in classpath passed to task rather than Ant's classpath.</td>
<td><a href="http://www.junit.org/" target="_top">http://www.junit.org/</a></td>
</tr>
<tr>
@@ -698,7 +698,7 @@ advised to do it by the user mailing list.


<hr>
<p align="center">Copyright &copy; 2000-2005 The Apache Software Foundation. All rights
<p align="center">Copyright &copy; 2000-2006 The Apache Software Foundation. All rights
Reserved.</p>

</body>


+ 5
- 1
src/main/org/apache/tools/ant/AntClassLoader.java View File

@@ -1,5 +1,5 @@
/*
* Copyright 2000-2005 The Apache Software Foundation
* Copyright 2000-2006 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -1490,4 +1490,8 @@ public class AntClassLoader extends ClassLoader implements SubBuildListener {
}
}

public String toString() {
return "AntClassLoader[" + getClasspath() + "]";
}

}

+ 8
- 7
src/main/org/apache/tools/ant/taskdefs/optional/junit/FormatterElement.java View File

@@ -1,5 +1,5 @@
/*
* Copyright 2001-2004 The Apache Software Foundation
* Copyright 2001-2004,2006 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -188,14 +188,14 @@ public class FormatterElement {
/**
* @since Ant 1.2
*/
JUnitResultFormatter createFormatter() throws BuildException {
JUnitTaskMirror.JUnitResultFormatterMirror createFormatter() throws BuildException {
return createFormatter(null);
}

/**
* @since Ant 1.6
*/
JUnitResultFormatter createFormatter(ClassLoader loader)
JUnitTaskMirror.JUnitResultFormatterMirror createFormatter(ClassLoader loader)
throws BuildException {

if (classname == null) {
@@ -210,7 +210,9 @@ public class FormatterElement {
f = Class.forName(classname, true, loader);
}
} catch (ClassNotFoundException e) {
throw new BuildException(e);
throw new BuildException("Using loader " + loader + " on class " + classname + ": " + e, e);
} catch (NoClassDefFoundError e) {
throw new BuildException("Using loader " + loader + " on class " + classname + ": " + e, e);
}

Object o = null;
@@ -222,12 +224,11 @@ public class FormatterElement {
throw new BuildException(e);
}

if (!(o instanceof JUnitResultFormatter)) {
if (!(o instanceof JUnitTaskMirror.JUnitResultFormatterMirror)) {
throw new BuildException(classname
+ " is not a JUnitResultFormatter");
}

JUnitResultFormatter r = (JUnitResultFormatter) o;
JUnitTaskMirror.JUnitResultFormatterMirror r = (JUnitTaskMirror.JUnitResultFormatterMirror) o;

if (useFile && outFile != null) {
try {


+ 2
- 2
src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitResultFormatter.java View File

@@ -1,5 +1,5 @@
/*
* Copyright 2001-2002,2004 The Apache Software Foundation
* Copyright 2001-2002,2004,2006 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,7 +26,7 @@ import org.apache.tools.ant.BuildException;
* testrun.
*
*/
public interface JUnitResultFormatter extends TestListener {
public interface JUnitResultFormatter extends TestListener, JUnitTaskMirror.JUnitResultFormatterMirror {
/**
* The whole testsuite started.
*/


+ 111
- 32
src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java View File

@@ -24,6 +24,7 @@ import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
@@ -34,9 +35,6 @@ import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Vector;
import junit.framework.AssertionFailedError;
import junit.framework.Test;
import junit.framework.TestResult;
import org.apache.tools.ant.AntClassLoader;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
@@ -134,7 +132,7 @@ public class JUnitTask extends Task {
private boolean summary = false;
private boolean reloading = true;
private String summaryValue = "";
private JUnitTestRunner runner = null;
private JUnitTaskMirror.JUnitTestRunnerMirror runner = null;

private boolean newEnvironment = false;
private Environment env = new Environment();
@@ -148,6 +146,9 @@ public class JUnitTask extends Task {
private Permissions perm = null;
private ForkMode forkMode = new ForkMode("perTest");

private boolean splitJunit = false;
private JUnitTaskMirror delegate;

private static final int STRING_BUFFER_SIZE = 128;
/**
* @since Ant 1.7
@@ -632,12 +633,81 @@ public class JUnitTask extends Task {
*/
public void init() {
antRuntimeClasses = new Path(getProject());
addClasspathEntry("/junit/framework/TestCase.class");
splitJunit = !addClasspathEntry("/junit/framework/TestCase.class");
addClasspathEntry("/org/apache/tools/ant/launch/AntMain.class");
addClasspathEntry("/org/apache/tools/ant/Task.class");
addClasspathEntry("/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.class");
}

private static JUnitTaskMirror createMirror(JUnitTask task, ClassLoader loader) {
try {
loader.loadClass("junit.framework.Test"); // sanity check
} catch (ClassNotFoundException e) {
throw new BuildException(
"The <classpath> for <junit> must include junit.jar if not in Ant's own classpath",
e, task.getLocation());
}
try {
Class c = loader.loadClass(JUnitTaskMirror.class.getName() + "Impl");
if (c.getClassLoader() != loader) {
throw new BuildException("Overdelegating loader", task.getLocation());
}
Constructor cons = c.getConstructor(new Class[] {JUnitTask.class});
return (JUnitTaskMirror) cons.newInstance(new Object[] {task});
} catch (Exception e) {
throw new BuildException(e, task.getLocation());
}
}

private final class SplitLoader extends AntClassLoader {

public SplitLoader(ClassLoader parent, Path path) {
super(parent, getProject(), path, true);
}

// forceLoadClass is not convenient here since it would not
// properly deal with inner classes of these classes.
protected synchronized Class loadClass(String classname, boolean resolve)
throws ClassNotFoundException {
Class theClass = findLoadedClass(classname);
if (theClass != null) {
return theClass;
}
if (isSplit(classname)) {
theClass = findClass(classname);
if (resolve) {
resolveClass(theClass);
}
return theClass;
} else {
return super.loadClass(classname, resolve);
}
}

private final String[] SPLIT_CLASSES = {
"BriefJUnitResultFormatter",
"JUnitResultFormatter",
"JUnitTaskMirrorImpl",
"JUnitTestRunner",
"JUnitVersionHelper",
"OutErrSummaryJUnitResultFormatter",
"PlainJUnitResultFormatter",
"SummaryJUnitResultFormatter",
"XMLJUnitResultFormatter",
};

private boolean isSplit(String classname) {
String simplename = classname.substring(classname.lastIndexOf('.') + 1);
for (int i = 0; i < SPLIT_CLASSES.length; i++) {
if (simplename.equals(SPLIT_CLASSES[i]) || simplename.startsWith(SPLIT_CLASSES[i] + '$')) {
return true;
}
}
return false;
}

}
/**
* Runs the testcase.
*
@@ -645,6 +715,18 @@ public class JUnitTask extends Task {
* @since Ant 1.2
*/
public void execute() throws BuildException {
ClassLoader myLoader = JUnitTask.class.getClassLoader();
ClassLoader mirrorLoader;
if (splitJunit) {
Path path = new Path(getProject());
path.add(antRuntimeClasses);
path.add(getCommandline().getClasspath());
mirrorLoader = new SplitLoader(myLoader, path);
} else {
mirrorLoader = myLoader;
}
delegate = createMirror(this, mirrorLoader);

List testLists = new ArrayList();

boolean forkPerTest = forkMode.getValue().equals(ForkMode.PER_TEST);
@@ -672,6 +754,10 @@ public class JUnitTask extends Task {
}
} finally {
deleteClassLoader();
if (mirrorLoader instanceof SplitLoader) {
((SplitLoader) mirrorLoader).cleanup();
}
delegate = null;
}
}

@@ -1061,18 +1147,22 @@ public class JUnitTask extends Task {
try {
log("Using System properties " + System.getProperties(),
Project.MSG_VERBOSE);
createClassLoader();
if (splitJunit) {
classLoader = (AntClassLoader) delegate.getClass().getClassLoader();
} else {
createClassLoader();
}
if (classLoader != null) {
classLoader.setThreadContextLoader();
}
runner = new JUnitTestRunner(test, test.getHaltonerror(),
runner = delegate.newJUnitTestRunner(test, test.getHaltonerror(),
test.getFiltertrace(),
test.getHaltonfailure(), false,
true, classLoader);
if (summary) {

SummaryJUnitResultFormatter f =
new SummaryJUnitResultFormatter();
JUnitTaskMirror.SummaryJUnitResultFormatterMirror f =
delegate.newSummaryJUnitResultFormatter();
f.setWithOutAndErr("withoutanderr"
.equalsIgnoreCase(summaryValue));
f.setOutput(getDefaultOutput());
@@ -1186,7 +1276,7 @@ public class JUnitTask extends Task {
if (fe.getUseFile()) {
String base = test.getOutfile();
if (base == null) {
base = JUnitTestRunner.IGNORED_FILE_NAME;
base = JUnitTaskMirror.JUnitTestRunnerMirror.IGNORED_FILE_NAME;
}
String filename = base + fe.getExtension();
File destFile = new File(test.getTodir(), filename);
@@ -1204,9 +1294,10 @@ public class JUnitTask extends Task {
* getResource doesn't contain the name of the archive.</p>
*
* @param resource resource that one wants to lookup
* @return true if something was in fact added
* @since Ant 1.4
*/
protected void addClasspathEntry(String resource) {
protected boolean addClasspathEntry(String resource) {
/*
* pre Ant 1.6 this method used to call getClass().getResource
* while Ant 1.6 will call ClassLoader.getResource().
@@ -1228,8 +1319,10 @@ public class JUnitTask extends Task {
if (f != null) {
log("Found " + f.getAbsolutePath(), Project.MSG_DEBUG);
antRuntimeClasses.createPath().setLocation(f);
return true;
} else {
log("Couldn\'t find " + resource, Project.MSG_DEBUG);
return false;
}
}

@@ -1269,7 +1362,7 @@ public class JUnitTask extends Task {
for (int i = 0; i < feArray.length; i++) {
FormatterElement fe = feArray[i];
File outFile = getOutput(fe, test);
JUnitResultFormatter formatter = fe.createFormatter(classLoader);
JUnitTaskMirror.JUnitResultFormatterMirror formatter = fe.createFormatter(classLoader);
if (outFile != null && formatter != null) {
try {
OutputStream out = new FileOutputStream(outFile);
@@ -1280,7 +1373,7 @@ public class JUnitTask extends Task {
}
}
if (summary) {
SummaryJUnitResultFormatter f = new SummaryJUnitResultFormatter();
JUnitTaskMirror.SummaryJUnitResultFormatterMirror f = delegate.newSummaryJUnitResultFormatter();
f.setWithOutAndErr("withoutanderr".equalsIgnoreCase(summaryValue));
addVmExit(test, f, getDefaultOutput(), message);
}
@@ -1291,23 +1384,9 @@ public class JUnitTask extends Task {
* Only used from the logVmExit method.
* @since Ant 1.7
*/
private void addVmExit(JUnitTest test, JUnitResultFormatter formatter,
private void addVmExit(JUnitTest test, JUnitTaskMirror.JUnitResultFormatterMirror formatter,
OutputStream out, final String message) {
formatter.setOutput(out);
formatter.startTestSuite(test);

//the trick to integrating test output to the formatter, is to
//create a special test class that asserts an error
//and tell the formatter that it raised.
Test t = new Test() {
public int countTestCases() { return 1; }
public void run(TestResult r) {
throw new AssertionFailedError(message);
}
};
formatter.startTest(t);
formatter.addError(t, new AssertionFailedError(message));
formatter.endTestSuite(test);
delegate.addVmExit(test, formatter, out, message);
}

/**
@@ -1535,9 +1614,9 @@ public class JUnitTask extends Task {
// everything otherwise just log a statement
boolean fatal = result.timedOut || result.crashed;
boolean errorOccurredHere =
result.exitCode == JUnitTestRunner.ERRORS || fatal;
result.exitCode == JUnitTaskMirror.JUnitTestRunnerMirror.ERRORS || fatal;
boolean failureOccurredHere =
result.exitCode != JUnitTestRunner.SUCCESS || fatal;
result.exitCode != JUnitTaskMirror.JUnitTestRunnerMirror.SUCCESS || fatal;
if (errorOccurredHere || failureOccurredHere) {
if ((errorOccurredHere && test.getHaltonerror())
|| (failureOccurredHere && test.getHaltonfailure())) {
@@ -1559,7 +1638,7 @@ public class JUnitTask extends Task {
}

protected class TestResultHolder {
public int exitCode = JUnitTestRunner.ERRORS;
public int exitCode = JUnitTaskMirror.JUnitTestRunnerMirror.ERRORS;
public boolean timedOut = false;
public boolean crashed = false;
}


+ 110
- 0
src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskMirror.java View File

@@ -0,0 +1,110 @@
/*
* Copyright 2006 The Apache Software Foundation
*
* Licensed 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.junit;

import java.io.IOException;
import java.io.OutputStream;
import org.apache.tools.ant.AntClassLoader;
import org.apache.tools.ant.types.Permissions;

/**
* Handles the portions of {@link JUnitTask} which need to directly access
* actual JUnit classes, so that junit.jar need not be on Ant's startup classpath.
* Neither JUnitTask.java nor JUnitTaskMirror.java nor their transitive static
* deps may import any junit.** classes!
* Specifically, need to not refer to
* - JUnitResultFormatter or its subclasses
* - JUnitVersionHelper
* - JUnitTestRunner
* Cf. {@link JUnitTask.SplitLoader#isSplit}
* Public only to permit access from classes in this package; do not use directly.
*
* @author refactoring tricks by Jesse Glick, real code by others
* @since 1.7
* @see "bug #38799"
*/
public interface JUnitTaskMirror {
void addVmExit(JUnitTest test, JUnitResultFormatterMirror formatter,
OutputStream out, final String message);
JUnitTestRunnerMirror newJUnitTestRunner(JUnitTest test, boolean haltOnError,
boolean filterTrace, boolean haltOnFailure, boolean showOutput,
boolean logTestListenerEvents, AntClassLoader classLoader);

SummaryJUnitResultFormatterMirror newSummaryJUnitResultFormatter();

public interface JUnitResultFormatterMirror {

void setOutput(OutputStream outputStream);

}

public interface SummaryJUnitResultFormatterMirror extends JUnitResultFormatterMirror {

void setWithOutAndErr(boolean value);

}

public interface JUnitTestRunnerMirror {

/**
* Used in formatter arguments as a placeholder for the basename
* of the output file (which gets replaced by a test specific
* output file name later).
*
* @since Ant 1.6.3
*/
String IGNORED_FILE_NAME = "IGNORETHIS";

/**
* No problems with this test.
*/
int SUCCESS = 0;
/**
* Some tests failed.
*/
int FAILURES = 1;

/**
* An error occurred.
*/
int ERRORS = 2;

void setPermissions(Permissions perm);
void run();

void addFormatter(JUnitResultFormatterMirror formatter);
int getRetCode();
void handleErrorFlush(String output);
void handleErrorOutput(String output);
void handleOutput(String output);
int handleInput(byte[] buffer, int offset, int length) throws IOException;
void handleFlush(String output);

}
}

+ 72
- 0
src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskMirrorImpl.java View File

@@ -0,0 +1,72 @@
/*
* Copyright 2006 The Apache Software Foundation
*
* Licensed 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.junit;

import java.io.OutputStream;
import junit.framework.AssertionFailedError;
import junit.framework.Test;
import junit.framework.TestResult;
import org.apache.tools.ant.AntClassLoader;

/**
* Implementation of the part of the junit task which can directly refer to junit.* classes.
* Public only to permit use of reflection; do not use directly.
* @see JUnitTaskMirror
* @see "bug #38799"
* @since 1.7
*/
public final class JUnitTaskMirrorImpl implements JUnitTaskMirror {
private final JUnitTask task;
public JUnitTaskMirrorImpl(JUnitTask task) {
this.task = task;
}
public void addVmExit(JUnitTest test, JUnitResultFormatterMirror _formatter,
OutputStream out, final String message) {
JUnitResultFormatter formatter = (JUnitResultFormatter) _formatter;
formatter.setOutput(out);
formatter.startTestSuite(test);
//the trick to integrating test output to the formatter, is to
//create a special test class that asserts an error
//and tell the formatter that it raised.
Test t = new Test() {
public int countTestCases() { return 1; }
public void run(TestResult r) {
throw new AssertionFailedError(message);
}
};
formatter.startTest(t);
formatter.addError(t, new AssertionFailedError(message));
formatter.endTestSuite(test);
}

public JUnitTaskMirror.JUnitTestRunnerMirror newJUnitTestRunner(JUnitTest test,
boolean haltOnError, boolean filterTrace, boolean haltOnFailure,
boolean showOutput, boolean logTestListenerEvents, AntClassLoader classLoader) {
return new JUnitTestRunner(test, haltOnError, filterTrace, haltOnFailure,
showOutput, logTestListenerEvents, classLoader);
}

public JUnitTaskMirror.SummaryJUnitResultFormatterMirror newSummaryJUnitResultFormatter() {
return new SummaryJUnitResultFormatter();
}
}

+ 12
- 32
src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java View File

@@ -1,5 +1,5 @@
/*
* Copyright 2000-2005 The Apache Software Foundation
* Copyright 2000-2006 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -62,31 +62,7 @@ import org.apache.tools.ant.util.TeeOutputStream;
* @since Ant 1.2
*/

public class JUnitTestRunner implements TestListener {

/**
* No problems with this test.
*/
public static final int SUCCESS = 0;

/**
* Some tests failed.
*/
public static final int FAILURES = 1;

/**
* An error occurred.
*/
public static final int ERRORS = 2;

/**
* Used in formatter arguments as a placeholder for the basename
* of the output file (which gets replaced by a test specific
* output file name later).
*
* @since Ant 1.6.3
*/
public static final String IGNORED_FILE_NAME = "IGNORETHIS";
public class JUnitTestRunner implements TestListener, JUnitTaskMirror.JUnitTestRunnerMirror {

/**
* Holds the registered formatters.
@@ -441,7 +417,7 @@ public class JUnitTestRunner implements TestListener {
perm = permissions;
}

protected void handleOutput(String output) {
public void handleOutput(String output) {
if (!logTestListenerEvents && output.startsWith(JUnitTask.TESTLISTENER_PREFIX))
; // ignore
else if (systemOut != null) {
@@ -454,24 +430,24 @@ public class JUnitTestRunner implements TestListener {
*
* @since Ant 1.6
*/
protected int handleInput(byte[] buffer, int offset, int length)
public int handleInput(byte[] buffer, int offset, int length)
throws IOException {
return -1;
}

protected void handleErrorOutput(String output) {
public void handleErrorOutput(String output) {
if (systemError != null) {
systemError.print(output);
}
}

protected void handleFlush(String output) {
public void handleFlush(String output) {
if (systemOut != null) {
systemOut.print(output);
}
}

protected void handleErrorFlush(String output) {
public void handleErrorFlush(String output) {
if (systemError != null) {
systemError.print(output);
}
@@ -505,6 +481,10 @@ public class JUnitTestRunner implements TestListener {
formatters.addElement(f);
}

public void addFormatter(JUnitTaskMirror.JUnitResultFormatterMirror f) {
formatters.addElement((JUnitResultFormatter) f);
}

/**
* Entry point for standalone (forked) mode.
*
@@ -645,7 +625,7 @@ public class JUnitTestRunner implements TestListener {
test.getOutfile() + fe.getExtension());
fe.setOutfile(destFile);
}
runner.addFormatter(fe.createFormatter());
runner.addFormatter((JUnitResultFormatter) fe.createFormatter());
}
}



+ 1
- 1
src/main/org/apache/tools/ant/taskdefs/optional/junit/SummaryJUnitResultFormatter.java View File

@@ -29,7 +29,7 @@ import org.apache.tools.ant.BuildException;
*
*/

public class SummaryJUnitResultFormatter implements JUnitResultFormatter {
public class SummaryJUnitResultFormatter implements JUnitResultFormatter, JUnitTaskMirror.SummaryJUnitResultFormatterMirror {

/**
* Formatter for timings.


+ 5
- 1
xdocs/faq.xml View File

@@ -1386,6 +1386,10 @@ mv /tmp/foo $ANT_HOME/bin/antRun
<code>org.apache.tools.ant.taskdefs.XSLTLiaison</code>
class.</p>

<p><em>As of Ant 1.7</em> <code>&lt;junit&gt;</code> no longer
requires you to have <code>junit.jar</code> in Ant's startup
classpath even if <code>ant-junit.jar</code> is present there.</p>

<p>Ant&apos;s class loader implementation uses Java&apos;s
delegation model, see <a
href="http://java.sun.com/products/jdk/1.2/docs/api/java/lang/ClassLoader.html">http://java.sun.com/products/jdk/1.2/docs/api/java/lang/ClassLoader.html</a>
@@ -1776,4 +1780,4 @@ mv /tmp/foo $ANT_HOME/bin/antRun
</faq>
</faqsection>

</document>
</document>

Loading…
Cancel
Save