On Jenkins with Katalon Plugin, HTML report and CSV report are not generated. There is no problem with the reports when running the same project in KSE locally.
In order to use Twilio functionality, the twilio-8.36.0-jar-with-dependencies.jar was added into the Driver folder as per Libraries management | Katalon Docs
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:
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 com.ctc.wsts.sr* package.
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:
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.
Here we see that the com.kms.katalon.core.logging.TestSuiteXMLLogParser.processFile() calls 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.
Why TestSuiteXMLLogParser is linked to com.ctc.wstx.sr.BasicStreamReader class? — You can find the reason by reading the source code.
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.ctc.wstx.sr.
Conclustion
com.kms.katalon.core.logging.TestUiteXMLLogParser class is too fragile. It is broken by Jenkins runtime environment.
A corner-cutting solution could be: create a logger.dtd file with empty content, place it beside the exectuion0.log file. You will get no more FileNotFoundException. Emptiness of logger.dtd would do nothing harmful.
I’m just wondering why it’s hapenning when the twilio-8.36.0-jar-with-dependencies.jar is in the Driver folder. Could it be somehow related to the fact that Katalon Plugin and the twilio-8.36.0-jar-with-dependencies.jar are using the same jars (as per https://mvnrepository.com/artifact/com.twilio.sdk/twilio/8.36.0):
I don’t think so. As long as the class name is the same and the version number is the same, eigher will do. It doesn’t matter from which jar the class is loaded.
It is impossible to predict what will happen due to this version inconsistency.
4.5.13 & 4.5.1 ---- which version jar will be used? Either of them. Just I don’t know. It depends on how the Java Classloader is configured in the runtime environment. See Java Classloader - Handling Multiple Versions of The Same Class - DZone for your interest. I am sure that, Katalon Studio and Jenkins, both would use their own classloader. I know nothing about their implementation.
Thank you @kazurayam for sharing this with me. I already raised the issue to our product team and asked them for the suggestions and expected timeline for solution (if any). I’ll keep you posted once the response is returned. Thank you.
Hi all, we got the confirmation that the issue is acknowledged and will plan for an improvement in the next release. Once again, thank you for your sharing. Best.