While running a Jenkins job with Katalon plugin, I’m getting the following WARN:
… java.io.FileNotFoundException … Logger.dtd
This is a frequently asked question in XML processing in Java.
I will tell you what I found. The program (KatalonReportListener) tried to read a
<projectDir>/Reports/.../execution0.log and failed. The file is a XML file which starts with 2 lines:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE log SYSTEM "logger.dtd">
The program tried to find the file named
logger.dtd and could not, so the program failed. However you would not have the
logger.dtd file, and the DTD file is usually not necessary to process the XML. So a common practice is to setup XML parser (XML Streaming Parser) to ignore the reference to the DTD. The following post is a sample where people ignore DTD.
I guess, Katalon Studio equips this sort of trick to ignore DTD. Therefore your test&report task runs OK on Katalon Studio stand alone (not in Jenkins).
However, when your test&report task runs integrated in Jenkins, I suppose this trick to ignore DTD disappers and a FileNotFoundException occured. Why? ---- the runtime environment in Jenkins has something to do with it.
In the stacktrace message, I found some names of classes belonging to
This package looks strange to me. I googled and found this package is included in the following project
I didn’t know this, but it seems to be a industry-wide well-known package of StAX (Streaming API for XML).
How this package was introduced into the runtime environment for @gdearest07?
I cloned Katalon Plugin for Jenkins project to my local Mac, and built it using Maven. I got the dependency:tree of the plugin. I got the following output:
[e[1;34mINFOe[m] Scanning for projects...
[e[1;33mWARNINGe[m] The POM for org.jenkins-ci.tools:maven-hpi-plugin:jar:3.11 is missing, no dependency information available
[e[1;33mWARNINGe[m] Failed to build parent project for org.jenkins-ci.plugins:katalon:hpi:1.0.32
[e[1;34mINFOe[m] e[1m-------------------< e[0;36morg.jenkins-ci.plugins:katalone[0;1m >-------------------e[m
[e[1;34mINFOe[m] e[1mBuilding Katalon Plugin 1.0.32e[m
[e[1;34mINFOe[m] e[1m--------------------------------[ hpi ]---------------------------------e[m
[e[1;34mINFOe[m] e[1m--- e[0;32mmaven-dependency-plugin:3.1.1:treee[m e[1m(default-cli)e[m @ e[36mkatalone[0;1m ---e[m
[e[1;34mINFOe[m] +- org.jenkins-ci.plugins:junit:jar:1.20:compile
[e[1;34mINFOe[m] | \- org.jenkins-ci.plugins:structs:jar:1.2:compile
[e[1;34mINFOe[m] | \- org.jenkins-ci:symbol-annotation:jar:1.2:compile
[e[1;34mINFOe[m] +- com.katalon:utils:jar:1.0.17:compile
[e[1;34mINFOe[m] | +- org.apache.commons:commons-lang3:jar:3.12.0:compile
[e[1;34mINFOe[m] | +- commons-io:commons-io:jar:2.11.0:compile
[e[1;34mINFOe[m] | +- com.fasterxml.jackson.core:jackson-databind:jar:2.13.3:compile
[e[1;34mINFOe[m] | | +- com.fasterxml.jackson.core:jackson-annotations:jar:2.13.3:compile
[e[1;34mINFOe[m] | | \- com.fasterxml.jackson.core:jackson-core:jar:2.13.3:compile
[e[1;34mINFOe[m] | \- org.rauschig:jarchivelib:jar:1.2.0:compile
[e[1;34mINFOe[m] +- org.apache.httpcomponents:httpclient:jar:4.5.13:compile
[e[1;34mINFOe[m] | +- org.apache.httpcomponents:httpcore:jar:4.4.13:compile
[e[1;34mINFOe[m] | \- commons-codec:commons-codec:jar:1.11:compile
[e[1;34mINFOe[m] +- org.jenkins-ci.plugins:plain-credentials:jar:1.3:compile
[e[1;34mINFOe[m] | \- org.jenkins-ci.plugins:credentials:jar:2.1.5:compile
[e[1;34mINFOe[m] | \- org.antlr:antlr4-runtime:jar:4.5:compile
[e[1;34mINFOe[m] | \- org.abego.treelayout:org.abego.treelayout.core:jar:1.0.1:compile
[e[1;34mINFOe[m] +- javax.servlet:javax.servlet-api:jar:3.1.0:provided
[e[1;34mINFOe[m] +- org.jenkins-ci.main:jenkins-core:jar:1.625.3:provided
[e[1;34mINFOe[m] | +- org.codehaus.woodstox:wstx-asl:jar:3.2.9:provided
Ah, Jenkins Core depends in the Woodstox library! I am sure that the Woodstox libary is available in all runtime environment under Jenkins. Now I found the reason why the
com.ctc.wsts.sr.* packages is there in the runtime evironment of @gdearest07’s test project.
My next question is this:
Here we see that the
com.ctc.wstx.sr.BasicStreamReader class. Is it what Katalon Developer intended?
I think Katalon Developer did not intended this. Katalon Developer doesn’t know anything about
com.ctx.wstx.sr.* package. They would be surprised to find the package is used in the runtime environment in Jenkins.
TestSuiteXMLLogParser is linked to
com.ctc.wstx.sr.BasicStreamReader class? — You can find the reason by reading the source code.
XMLInputFactory inputFactory = XmlInputFactoryProvider.newInstance();
Let’s see the javadoc of XmlInputFactoryProvider class at
Create a new instance of the factory.
This static method creates a new factory instance. This method uses the following ordered lookup procedure to determine the XMLInputFactory implementation class to load:
- Use the javax.xml.stream.XMLInputFactory system property.
- Use the properties file “lib/stax.properties” in the JRE directory. This configuration file is in standard java.util.Properties format and contains the fully qualified name of the implementation class with the key being the system property defined above.
- Use the service-provider loading facilities, defined by the
ServiceLoader class, to attempt to locate and load an implementation of the service using the default loading mechanism: the service-provider loading facility will use the current thread’s context class loader to attempt to load the service. If the context class loader is null, the system class loader will be used.
- Otherwise, the system-default implementation is returned.
I just guess:
- Jenkins applies one of the option 1, 2 or 3 to use
com.ctc.wstx.sr.\* package with precedence to the system-default
Katalon Developer naively assumed that nobody would do the option 1,2 and 3. They expected the option 4 (the system-default implementation of XMLInputFactory is used) will be applied always.
Now let me go back to the issue around
logger.dtd file. You can ignore
logger.dtd by configuring the StAX Parser class that implements XMLInputFactory. However, please note, the way to configure the StAX parser class is implementation specific. The StAX parser of
com.ctc.wstx.sr. package would require programmers to follow its own way to configure ingoring DTD. And the system-default implementation of XMLInputFactory would require them to following its own way, which is different from the
com.kms.katalon.core.logging.TestUiteXMLLogParser class is too fragile. It is broken by Jenkins runtime environment.
please escarate this issue to Katalon developers as appropriate