Browse Source

try to make OOM in <junit> less likely. PR 45536. Submitted by Steve Loughran who decided not to commit it himself :-)

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@1556001 13f79535-47bb-0310-9956-ffa450edef68
master
Stefan Bodewig 11 years ago
parent
commit
313479bb35
4 changed files with 111 additions and 28 deletions
  1. +4
    -0
      WHATSNEW
  2. +12
    -2
      src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java
  3. +45
    -17
      src/main/org/apache/tools/ant/taskdefs/optional/junit/PlainJUnitResultFormatter.java
  4. +50
    -9
      src/main/org/apache/tools/ant/util/DOMElementWriter.java

+ 4
- 0
WHATSNEW View File

@@ -91,6 +91,10 @@ Other changes:
* <sql> has a new outputencoding attribute. * <sql> has a new outputencoding attribute.
Bugzilla Report 39541 Bugzilla Report 39541


* changes to JUnitTestRunner and PlainJUnitResultFormatter to make
OutOfMemoryErrors less likely.
Bugzilla Report 45536

Changes from Ant 1.9.2 TO Ant 1.9.3 Changes from Ant 1.9.2 TO Ant 1.9.3
=================================== ===================================




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

@@ -558,8 +558,18 @@ public class JUnitTestRunner implements TestListener, JUnitTaskMirror.JUnitTestR
systemOut.close(); systemOut.close();
systemOut = null; systemOut = null;
if (startTestSuiteSuccess) { if (startTestSuiteSuccess) {
sendOutAndErr(new String(outStrm.toByteArray()),
new String(errStrm.toByteArray()));
String out, err;
try {
out = new String(outStrm.toByteArray());
} catch (OutOfMemoryError ex) {
out = "out of memory on output stream";
}
try {
err = new String(errStrm.toByteArray());
} catch (OutOfMemoryError ex) {
err = "out of memory on error stream";
}
sendOutAndErr(out, err);
} }
} }
fireEndTestSuite(); fireEndTestSuite();


+ 45
- 17
src/main/org/apache/tools/ant/taskdefs/optional/junit/PlainJUnitResultFormatter.java View File

@@ -117,6 +117,7 @@ public class PlainJUnitResultFormatter implements JUnitResultFormatter, IgnoredT
* @throws BuildException if unable to write the output * @throws BuildException if unable to write the output
*/ */
public void endTestSuite(JUnitTest suite) throws BuildException { public void endTestSuite(JUnitTest suite) throws BuildException {
try {
StringBuffer sb = new StringBuffer("Tests run: "); StringBuffer sb = new StringBuffer("Tests run: ");
sb.append(suite.runCount()); sb.append(suite.runCount());
sb.append(", Failures: "); sb.append(", Failures: ");
@@ -129,40 +130,49 @@ public class PlainJUnitResultFormatter implements JUnitResultFormatter, IgnoredT
sb.append(nf.format(suite.getRunTime() / ONE_SECOND)); sb.append(nf.format(suite.getRunTime() / ONE_SECOND));
sb.append(" sec"); sb.append(" sec");
sb.append(StringUtils.LINE_SEP); sb.append(StringUtils.LINE_SEP);
write(sb.toString());


// append the err and output streams to the log
// write the err and output streams to the log
if (systemOutput != null && systemOutput.length() > 0) { if (systemOutput != null && systemOutput.length() > 0) {
sb.append("------------- Standard Output ---------------")
.append(StringUtils.LINE_SEP)
.append(systemOutput)
.append("------------- ---------------- ---------------")
.append(StringUtils.LINE_SEP);
write("------------- Standard Output ---------------");
write(StringUtils.LINE_SEP);
write(systemOutput);
write("------------- ---------------- ---------------");
write(StringUtils.LINE_SEP);
} }


if (systemError != null && systemError.length() > 0) { if (systemError != null && systemError.length() > 0) {
sb.append("------------- Standard Error -----------------")
.append(StringUtils.LINE_SEP)
.append(systemError)
.append("------------- ---------------- ---------------")
.append(StringUtils.LINE_SEP);
write("------------- Standard Error -----------------");
write(StringUtils.LINE_SEP);
write(systemError);
write("------------- ---------------- ---------------");
write(StringUtils.LINE_SEP);
} }


sb.append(StringUtils.LINE_SEP);

write(StringUtils.LINE_SEP);
if (out != null) {
try {
wri.flush();
write(inner.toString());
} catch (IOException ioex) {
throw new BuildException("Unable to write output", ioex);
}
}
} finally {
if (out != null) { if (out != null) {
try { try {
out.write(sb.toString().getBytes());
wri.close(); wri.close();
out.write(inner.toString().getBytes());
out.flush();
} catch (IOException ioex) { } catch (IOException ioex) {
throw new BuildException("Unable to write output", ioex);
throw new BuildException("Unable to flush output", ioex);
} finally { } finally {
if (out != System.out && out != System.err) { if (out != System.out && out != System.err) {
FileUtils.close(out); FileUtils.close(out);
} }
wri = null;
out = null;
} }
} }
}
} }


/** /**
@@ -286,4 +296,22 @@ public class PlainJUnitResultFormatter implements JUnitResultFormatter, IgnoredT
public void testAssumptionFailure(Test test, Throwable throwable) { public void testAssumptionFailure(Test test, Throwable throwable) {
formatSkip(test, throwable.getMessage()); formatSkip(test, throwable.getMessage());
} }

/**
* Print out some text, and flush the output stream; encoding in the platform
* local default encoding.
* @param text text to write.
* @throws BuildException on IO Problems.
*/
private void write(String text) {
if (out == null) {
return;
}
try {
out.write(text.getBytes());
out.flush();
} catch (IOException ex) {
throw new BuildException("Unable to write output " + ex, ex);
}
}
} // PlainJUnitResultFormatter } // PlainJUnitResultFormatter

+ 50
- 9
src/main/org/apache/tools/ant/util/DOMElementWriter.java View File

@@ -21,6 +21,7 @@ package org.apache.tools.ant.util;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.io.Writer; import java.io.Writer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@@ -233,7 +234,7 @@ public class DOMElementWriter {


case Node.CDATA_SECTION_NODE: case Node.CDATA_SECTION_NODE:
out.write("<![CDATA["); out.write("<![CDATA[");
out.write(encodedata(((Text) child).getData()));
encodedata(out, ((Text) child).getData());
out.write("]]>"); out.write("]]>");
break; break;


@@ -486,19 +487,59 @@ public class DOMElementWriter {
* href="http://www.w3.org/TR/1998/REC-xml-19980210#sec-cdata-sect">http://www.w3.org/TR/1998/REC-xml-19980210#sec-cdata-sect</a>.</p> * href="http://www.w3.org/TR/1998/REC-xml-19980210#sec-cdata-sect">http://www.w3.org/TR/1998/REC-xml-19980210#sec-cdata-sect</a>.</p>
* @param value the value to be encoded. * @param value the value to be encoded.
* @return the encoded value. * @return the encoded value.

*/ */
public String encodedata(final String value) { public String encodedata(final String value) {
final StringWriter out = new StringWriter();
try {
encodedata(out, value);
} catch (IOException ex) {
throw new RuntimeException(ex);
}
return out.toString();
}

/**
* Drop characters that are illegal in XML documents and write the
* rest to the given writer.
*
* <p>Also ensure that we are not including an <code>]]&gt;</code>
* marker by replacing that sequence with
* <code>&amp;#x5d;&amp;#x5d;&amp;gt;</code>.</p>
*
* <p>See XML 1.0 2.2 <a
* href="http://www.w3.org/TR/1998/REC-xml-19980210#charsets">
* http://www.w3.org/TR/1998/REC-xml-19980210#charsets</a> and
* 2.7 <a
* href="http://www.w3.org/TR/1998/REC-xml-19980210#sec-cdata-sect">http://www.w3.org/TR/1998/REC-xml-19980210#sec-cdata-sect</a>.</p>
* @param value the value to be encoded.
* @param out where to write the encoded data to.
*/
public void encodedata(final Writer out, final String value) throws IOException {
final int len = value.length(); final int len = value.length();
StringBuffer sb = new StringBuffer(len);
for (int i = 0; i < len; ++i) {
final char c = value.charAt(i);
if (isLegalCharacter(c)) {
sb.append(c);
int prevEnd = 0, cdataEndPos = value.indexOf("]]>");
while (prevEnd < len) {
final int end = (cdataEndPos < 0 ? len : cdataEndPos);
// Write out stretches of legal characters in the range [prevEnd, end).
for (int prevLegalCharPos = prevEnd; prevLegalCharPos < end; /*empty*/) {
int illegalCharPos;
for (illegalCharPos = prevLegalCharPos; true; ++illegalCharPos) {
if (illegalCharPos >= end
|| !isLegalCharacter(value.charAt(illegalCharPos))) {
break;
}
}
out.write(value, prevLegalCharPos, illegalCharPos - prevLegalCharPos);
prevLegalCharPos = illegalCharPos + 1;
} }
}


return sb.substring(0).replace("]]>", "]]]]><![CDATA[>");
if (cdataEndPos >= 0) {
out.write("]]]]><![CDATA[>");
prevEnd = cdataEndPos + 3;
cdataEndPos = value.indexOf("]]>", prevEnd);
} else {
prevEnd = end;
}
}
} }


/** /**


Loading…
Cancel
Save