git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@1556001 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -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 | ||||
| =================================== | =================================== | ||||
| @@ -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(); | ||||
| @@ -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 | ||||
| @@ -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>]]></code> | |||||
| * marker by replacing that sequence with | |||||
| * <code>&#x5d;&#x5d;&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; | |||||
| } | |||||
| } | |||||
| } | } | ||||
| /** | /** | ||||