Project

Profile

Help

Bug #6464

open

Saxon prints stack trace when MessageListener throws an exception

Added by Lars Marius Garshol 5 months ago. Updated 4 months ago.

Status:
New
Priority:
Low
Assignee:
-
Category:
-
Sprint/Milestone:
-
Start date:
2024-07-03
Due date:
% Done:

0%

Estimated time:
Legacy ID:
Applies to branch:
Fix Committed on Branch:
Fixed in Maintenance Release:
Platforms:

Description

Let's say I make the following minimal Java program, which throws a RuntimeException whenever there is an xsl:message:

package com.realtaonline.render.utils;

import java.io.File;

import javax.xml.transform.SourceLocator;
import javax.xml.transform.stream.StreamSource;
import net.sf.saxon.s9api.MessageListener2;
import net.sf.saxon.s9api.Processor;
import net.sf.saxon.s9api.QName;
import net.sf.saxon.s9api.SaxonApiException;
import net.sf.saxon.s9api.XdmNode;
import net.sf.saxon.s9api.XsltCompiler;
import net.sf.saxon.s9api.XsltExecutable;
import net.sf.saxon.s9api.XsltTransformer;

public class Transformer {

  public static void main(String[] args) throws Exception {
    Processor proc = new Processor(true);
    XsltCompiler compiler = proc.newXsltCompiler();

    RealtaMessageListener listener = new RealtaMessageListener();
    StreamSource ssource = new StreamSource(new File(args[0]));
    XsltExecutable executable = compiler.compile(ssource);
    XsltTransformer transformer = executable.load();

    transformer.setMessageListener(listener);

    transformer.setSource(new StreamSource(new File(args[1])));
    transformer.setDestination(proc.newSerializer(new File(args[2])));
    try {
      transformer.transform();
    } catch (RuntimeException e) {
      System.out.println("We caught the exception, nothing to see here");
    }
  }

  public static class RealtaMessageListener implements MessageListener2 {
    public void message​(XdmNode content, QName errorCode, boolean terminate,
                        SourceLocator locator) {
      throw new RuntimeException("Transform aborted by xsl:message #1");
    }
  }
}

As you see, we catch the RuntimeException at the top level, so the only output should be the line saying we caught it.

However, if I run that with this XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
  <xsl:template match="/">
    <xsl:message terminate="true">
      Whoooo
    </xsl:message>
  </xsl:template>
</xsl:stylesheet>

the output I get is:

MacBook-Pro-3:java larsga$ java -cp xmlserver/target/xmlserver-1.0-SNAPSHOT-jar-with-dependencies.jar com.realtaonline.render.utils.Transformer ~/tmp/tst.xsl ~/tmp/tst.xsl ~/tmp/out.xml
java.lang.RuntimeException: Transform aborted by xsl:message #1
	at com.realtaonline.render.utils.Transformer$RealtaMessageListener.message(Transformer.java:44)
	at net.sf.saxon.s9api.AbstractXsltTransformer.lambda$setMessageListener$0(AbstractXsltTransformer.java:305)
	at net.sf.saxon.expr.instruct.MessageInstr$MessageInstrElaborator.lambda$elaborateForPush$0(MessageInstr.java:351)
	at net.sf.saxon.expr.instruct.TemplateRule.applyLeavingTail(TemplateRule.java:376)
	at net.sf.saxon.trans.Mode.handleRuleNotNull(Mode.java:587)
	at net.sf.saxon.trans.Mode.applyTemplates(Mode.java:521)
	at net.sf.saxon.trans.XsltController.applyTemplates(XsltController.java:684)
	at net.sf.saxon.s9api.AbstractXsltTransformer.applyTemplatesToSource(AbstractXsltTransformer.java:430)
	at net.sf.saxon.s9api.XsltTransformer.transform(XsltTransformer.java:358)
	at com.realtaonline.render.utils.Transformer.main(Transformer.java:33)
We caught the exception, nothing to see here

So clearly Saxon is printing the stack trace when it catches the exception, before passing it on.

These stack traces appear in our consoles and logs and confuse people into thinking there actually is something wrong in cases where there isn't. It would be great if you could fix this.

Actions #1

Updated by Martin Honnen 5 months ago

I think you are seeing https://www.saxonica.com/html/documentation12/javadoc/net/sf/saxon/lib/StandardLogger.html writing to System.err. You can set up a different Logger to write to a File or PrintStream or Writer or discard anything. See https://www.saxonica.com/html/documentation12/javadoc/net/sf/saxon/Configuration.html#setLogger(net.sf.saxon.lib.Logger).

Actions #2

Updated by Lars Marius Garshol 4 months ago

Thank you for the input, Martin. I tried it by implemented a Logger:

package com.realtaonline.render.xmlserver;  
  
import net.sf.saxon.lib.Logger;  
  
public class RealtaLogger extends Logger {  
public void println​(String message, int severity) {  
}  
public void warning(String message) {  
}  
public void info(String message) {  
}  
public void error(String message) {  
}  
public void disaster(String message) {  
}  
}  

and added two lines to set it in the configuration:

public static void main(String[] args) throws Exception {  
Processor proc = new Processor(true);  
Configuration cfg = proc.getUnderlyingConfiguration();  
cfg.setLogger(new RealtaLogger());  
XsltCompiler compiler = proc.newXsltCompiler();  

The output is exactly the same as before. So the message is clearly not coming from a Logger.

Actions #3

Updated by Michael Kay 4 months ago

I have so far failed to reproduce the problem.

Could you clarify which version of Saxon you are using?

Actions #4

Updated by Michael Kay 4 months ago

  • Subject changed from Saxon prints stack trace to console to Saxon prints stack trace when MessageListener throws an exception
Actions #5

Updated by Lars Marius Garshol 4 months ago

Running “net.sf.saxon.Transform -versionmsg” on the jar I that contains the minimal test case:

SaxonJ-PE 12.4 from Saxonica

On my disk it’s:

MacBook-Pro-3:java larsga$ ll ../jar/saxonpe/saxonpe.jar
-rw-r--r-- 1 larsga staff 6422837 Dec 21 2023 ../jar/saxonpe/saxonpe.jar
MacBook-Pro-3:java larsga$ sha1sum $_
d9877062db0c5b876c3b5c46de13066235d03eea ../jar/saxonpe/saxonpe.jar
MacBook-Pro-3:java larsga$

Please register to edit this issue

Also available in: Atom PDF