Browse Source

Allow JUnit to reuse the same classloader when fork is set to false

Submitted by: michael_beauregard at transcanada dot com


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@274682 13f79535-47bb-0310-9956-ffa450edef68
master
Antoine Levy-Lambert 22 years ago
parent
commit
9b60f270d4
3 changed files with 48 additions and 30 deletions
  1. +3
    -0
      WHATSNEW
  2. +7
    -0
      docs/manual/OptionalTasks/junit.html
  3. +38
    -30
      src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java

+ 3
- 0
WHATSNEW View File

@@ -297,6 +297,9 @@ Other changes:
* The xml formatter for JUnit will now honor test case names set with
setName. Bugzilla Report 17040.

* JUnit now has an attribute reloading, which, when set to false,
makes the task reuse the same class loader for a series of tests.

* <concat> now supports filtering and can check timestamps before
overriding a file. Bugzilla Report 18166.



+ 7
- 0
docs/manual/OptionalTasks/junit.html View File

@@ -149,6 +149,13 @@ elements</a>).</p>
<td align="center" valign="top">No; default is the project's base
directory.</td>
</tr>
<tr>
<td valign="top">reloading</td>
<td valign="top">Whether or not a new classloader should be instantiated for each test case.<br/>
Ignore if <code>fork</code> is set to true.
<em>Since Ant 1.6</em>.</td>
<td align="center" valign="top">No; default is <code>true</code>.</td>
</tr>
</table>

<p>By using the <code>errorproperty</code> and <code>failureproperty</code>


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

@@ -166,6 +166,7 @@ public class JUnitTask extends Task {

private Integer timeout = null;
private boolean summary = false;
private boolean reloading = true;
private String summaryValue = "";
private JUnitTestRunner runner = null;

@@ -177,6 +178,15 @@ public class JUnitTask extends Task {

private boolean showOutput = false;
private File tmpDir;
private AntClassLoader classLoader = null;
/**
* If true, force ant to re-classload all classes for each JUnit TestCase
*
* @param value force class reloading for each test case
*/
public void setReloading(boolean value) {
reloading = value;
}

/**
* If true, smartly filter the stack frames of
@@ -846,17 +856,17 @@ public class JUnitTask extends Task {
if (sysProperties != null) {
sysProperties.setSystem();
}
AntClassLoader cl = null;
try {
log("Using System properties " + System.getProperties(),
Project.MSG_VERBOSE);
cl = createClassLoader();
if (cl != null) {
cl.setThreadContextLoader();
createClassLoader();
if (classLoader != null) {
classLoader.setThreadContextLoader();
}
runner = new JUnitTestRunner(test, test.getHaltonerror(),
test.getFiltertrace(),
test.getHaltonfailure(), cl);
test.getHaltonfailure(), classLoader);
if (summary) {
log("Running " + test.getName(), Project.MSG_INFO);

@@ -878,7 +888,7 @@ public class JUnitTask extends Task {
} else {
fe.setOutput(getDefaultOutput());
}
runner.addFormatter(fe.createFormatter(cl));
runner.addFormatter(fe.createFormatter(classLoader));
}
}

@@ -888,8 +898,8 @@ public class JUnitTask extends Task {
if (sysProperties != null) {
sysProperties.restoreSystem();
}
if (cl != null) {
cl.resetThreadContextLoader();
if (classLoader != null) {
classLoader.resetThreadContextLoader();
}
}
}
@@ -1012,11 +1022,11 @@ public class JUnitTask extends Task {
*/

private void logTimeout(FormatterElement[] feArray, JUnitTest test) {
AntClassLoader cl = createClassLoader();
createClassLoader();
for (int i = 0; i < feArray.length; i++) {
FormatterElement fe = feArray[i];
File outFile = getOutput(fe, test);
JUnitResultFormatter formatter = fe.createFormatter(cl);
JUnitResultFormatter formatter = fe.createFormatter(classLoader);
if (outFile != null && formatter != null) {
try {
OutputStream out = new FileOutputStream(outFile);
@@ -1044,31 +1054,29 @@ public class JUnitTask extends Task {
* Creates and configures an AntClassLoader instance from the
* nested classpath element.
*
* @return null if there is no user-specified classpath.
*
* @since Ant 1.6
*/
private AntClassLoader createClassLoader() {
AntClassLoader cl = null;
private void createClassLoader() {
Path userClasspath = commandline.getClasspath();
if (userClasspath != null) {
Path classpath = (Path) userClasspath.clone();
if (includeAntRuntime) {
log("Implicitly adding " + antRuntimeClasses
+ " to CLASSPATH", Project.MSG_VERBOSE);
classpath.append(antRuntimeClasses);
if (reloading || classLoader == null) {
Path classpath = (Path) userClasspath.clone();
if (includeAntRuntime) {
log("Implicitly adding " + antRuntimeClasses
+ " to CLASSPATH", Project.MSG_VERBOSE);
classpath.append(antRuntimeClasses);
}
classLoader = getProject().createClassLoader(classpath);
log("Using CLASSPATH " + classLoader.getClasspath(),
Project.MSG_VERBOSE);
classLoader.setParentFirst(false);
classLoader.addJavaLibraries();
log("Using CLASSPATH " + classLoader.getClasspath(), Project.MSG_VERBOSE);
// make sure the test will be accepted as a TestCase
classLoader.addSystemPackageRoot("junit");
// will cause trouble in JDK 1.1 if omitted
classLoader.addSystemPackageRoot("org.apache.tools.ant");
}

cl = getProject().createClassLoader(classpath);
cl.setParentFirst(false);
cl.addJavaLibraries();
log("Using CLASSPATH " + cl.getClasspath(), Project.MSG_VERBOSE);

// make sure the test will be accepted as a TestCase
cl.addSystemPackageRoot("junit");
// will cause trouble in JDK 1.1 if omitted
cl.addSystemPackageRoot("org.apache.tools.ant");
}
return cl;
}
}

Loading…
Cancel
Save