junitreport:当有许多换行符/换行符时,xslt因StackOverflowError而失败

时间:2011-11-09 16:44:58

标签: java xslt ant junit

我正在使用ant 1.8.2。让我们说一个测试失败,堆栈溢出错误。

import junit.framework.TestCase;

 /**a failing test */
 public class FailingTest    extends TestCase
 {

    public void testFail() {
        testFail();// gives stackoverflow- result xml is now a large document
    }
 }

运行junitreport将失败并显示以下错误

  

[junitreport] jar:file://lib/ant-junit.jar!/org/apache/tools/ant/taskdefs/optional/junit/xsl/junit-frames.xsl:65:57:   致命错误! java.lang.StackOverflowError原因:   java.lang.StackOverflowError的

原因似乎是测试结果XML文件中的大文本内容。

 <testcase classname="chs.FailingTest" name="testFail" time="0.012">
      <error type="java.lang.StackOverflowError">java.lang.StackOverflowError
          at chs.FailingTest.testFail(FailingTest.java:14)
          at chs.FailingTest.testFail(FailingTest.java:14)
          at chs.FailingTest.testFail(FailingTest.java:14) ....

我猜xslt需要修剪并跳过大错误消息。有什么可能的解决办法?

//临时修复:从结果html中删除这么大的文本 在junit-xslt文件中需要编辑

<xsl:template name="br-replace">
    <xsl:param name="word"/>
    <xsl:if test="string-length($word)  &lt; 31024 "> //very large size here causes stackoverflow
    <xsl:choose>
      <xsl:when test="contains($word, '&#xa;')">
        <xsl:value-of select="substring-before($word, '&#xa;')"/>
        <br/>
        <xsl:call-template name="br-replace">
          <xsl:with-param name="word" select="substring-after($word, '&#xa;')"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$word"/>
      </xsl:otherwise>
    </xsl:choose>
    </xsl:if>
</xsl:template>

最终修复:看到下面的答案后,我检查了蚂蚁开发网站。 SVN有新的xslt:http://svn.apache.org/viewvc/ant/core/trunk/src/etc/junit-frames-xalan1.xsl?view=co&content-type=text%2Fplain,它将模板更新为

<xsl:template name="br-replace">
    <xsl:param name="word"/>
    <xsl:param name="br"><br/></xsl:param>
    <xsl:value-of select='stringutils:replace(string($word),"&#xA;",$br)'/>
</xsl:template>

2 个答案:

答案 0 :(得分:1)

将代码转换为XSLT 2.0:

<xsl:template name="br-replace">
    <xsl:param name="word"/>
    <xsl:for-each select="tokenize($word, '&#xa;')">
      <xsl:if test="position() != 1"><br/></xsl:if>
      <xsl:value-of select="."/>
    </xsl:for-each>
</xsl:template>

或者,使用Saxon作为XSLT处理器运行现有代码。 Saxon实现了尾部调用优化,它将这个递归模板转换为普通循环。

答案 1 :(得分:1)

   public void testFail() {
        testFail();// gives stackoverflow- result xml is now a large document
    }

此方法调用自身....没有退出点