Simplest SOAP Test doen't work in KS v8.0.x, Property 'http://javax.xml.XMLConstants/property/accessExternalDTD' is not recognized due to "accessExternalDTD

macOS 11.4 Big Sur

Katalon Studio Version

8.0.1

Katalon Studio logs

.log.zip (2.0 KB)

What I found

This seems to be an known issue to Katalon Team. I report it here again just to share information to those who newly encounter the problem.

I created a simplest SOAP API test project. A ZIP of the project is attached:

SimplestSOAP-API-Test.zip (104.5 KB)

I executed the Test Case “CalculatorTest”

import static com.kms.katalon.core.testobject.ObjectRepository.findTestObject

import com.kms.katalon.core.model.FailureHandling
import com.kms.katalon.core.testobject.ResponseObject
import com.kms.katalon.core.webservice.keyword.WSBuiltInKeywords as WS

ResponseObject response = WS.sendRequest(findTestObject('Calculator'), FailureHandling.CONTINUE_ON_FAILURE)

WS.verifyResponseStatusCode(response, 200)

String xmlString = response.getResponseBodyContent()
println(xmlString)

I got an Exception Stack trace:

2021-06-16 11:03:25.964 INFO  c.k.katalon.core.main.TestCaseExecutor   - --------------------
2021-06-16 11:03:25.968 INFO  c.k.katalon.core.main.TestCaseExecutor   - START Test Cases/CalculatorTest
2021-06-16 11:03:27.137 DEBUG testcase.CalculatorTest                  - 1: response = sendRequest(findTestObject("Calculator"), CONTINUE_ON_FAILURE)
log4j:WARN No appenders could be found for logger (org.apache.http.client.protocol.RequestAddCookies).
log4j:WARN Please initialize the log4j system properly.
2021-06-16 11:03:28.616 INFO  c.k.k.core.webservice.common.HarLogger   - HAR: /var/folders/7m/lm7d6nx51kj0kbtnsskz6r3m0000gn/T/Katalon/Test Cases/CalculatorTest/20210616_110322/requests/main/0.har
2021-06-16 11:03:28.760 DEBUG testcase.CalculatorTest                  - 2: verifyResponseStatusCode(response, 200)
2021-06-16 11:03:28.789 DEBUG testcase.CalculatorTest                  - 3: xmlString = response.getResponseBodyContent()
2021-06-16 11:03:28.835 ERROR c.k.katalon.core.main.TestCaseExecutor   - ❌ Test Cases/CalculatorTest FAILED.
Reason:
java.lang.IllegalArgumentException: Property 'http://javax.xml.XMLConstants/property/accessExternalDTD' is not recognized.
	at org.apache.xerces.jaxp.DocumentBuilderFactoryImpl.setAttribute(Unknown Source)
	at com.kms.katalon.util.DocumentBuilderProvider.newBuilderInstance(DocumentBuilderProvider.java:16)
	at com.kms.katalon.core.testobject.ResponseObject.getResponseBodyContent(ResponseObject.java:74)
	at com.kms.katalon.core.testobject.ResponseObject$getResponseBodyContent.call(Unknown Source)
	at CalculatorTest.run(CalculatorTest:11)
	at com.kms.katalon.core.main.ScriptEngine.run(ScriptEngine.java:194)
	at com.kms.katalon.core.main.ScriptEngine.runScriptAsRawText(ScriptEngine.java:119)
	at com.kms.katalon.core.main.TestCaseExecutor.runScript(TestCaseExecutor.java:398)
	at com.kms.katalon.core.main.TestCaseExecutor.doExecute(TestCaseExecutor.java:389)
	at com.kms.katalon.core.main.TestCaseExecutor.processExecutionPhase(TestCaseExecutor.java:368)
	at com.kms.katalon.core.main.TestCaseExecutor.accessMainPhase(TestCaseExecutor.java:360)
	at com.kms.katalon.core.main.TestCaseExecutor.execute(TestCaseExecutor.java:255)
	at com.kms.katalon.core.main.TestCaseMain.runTestCase(TestCaseMain.java:114)
	at com.kms.katalon.core.main.TestCaseMain.runTestCase(TestCaseMain.java:105)
	at com.kms.katalon.core.main.TestCaseMain$runTestCase$0.call(Unknown Source)
	at TempTestCase1623809002635.run(TempTestCase1623809002635.groovy:25)

2021-06-16 11:03:28.850 INFO  c.k.katalon.core.main.TestCaseExecutor   - END Test Cases/CalculatorTest

Here is the screenshot of Katalon Studio GUI when I got that error:

In the statck trace I found this line:

at com.kms.katalon.util.DocumentBuilderProvider.newBuilderInstance(DocumentBuilderProvider.java:16)

This message shows the exact location where the Exception was raised. I clicked the underlined DocumentBuilderProvier.java:16. Then Katalon Studio showed the source code of the class.

/*    */ public class DocumentBuilderProvider {
	/*    */ public static DocumentBuilder newBuilderInstance() throws ParserConfigurationException {
		/* 15 */ DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
		/* 16 */ dbFactory.setAttribute("http://javax.xml.XMLConstants/property/accessExternalDTD", "");
		/* 17 */ dbFactory.setAttribute("http://javax.xml.XMLConstants/property/accessExternalSchema", "");
		/* 18 */ return dbFactory.newDocumentBuilder();
		/*    */ }
	/*    */ }

This decompiled source code tells us that the com.kms.katalon.util.DocumentBuilderProvider class of KS v8.0.1 calls

/* 16 */ dbFactory.setAttribute("http://javax.xml.XMLConstants/property/accessExternalDTD", "");

This very statement is causing the `IllegalArgumentException: Property '“http://javax.xml.XMLConstants/property/accessExternalDTD” is not recognized.

In v 7.9.1

I tried the same in Katalon Studio v7.9.1. No exception was raised.

What I guess

The problematic statement:

/* 16 */ dbFactory.setAttribute("http://javax.xml.XMLConstants/property/accessExternalDTD", "");

I guess, this statement has been newly inserted in the KS v8.0.x. For what? I don’t know.
I guess, this statement was not there in the KS 7.9.0.
This is the reason why we see this exception only since KS v8.0.x.

Additional info

The sample project has a Test Case named “printXercesJarLocation”.

import org.apache.xerces.jaxp.DocumentBuilderFactoryImpl

URL u = DocumentBuilderFactoryImpl.class.getResource("/" + DocumentBuilderFactoryImpl.class.getName().replaceAll("\\.", "/") + ".class");

System.out.println(u);

When I ran it i got the following output.

jar:file:/Applications/Katalon%20Studio.app/Contents/Eclipse/plugins/org.codehaus.groovy_2.4.20.v202009301404-e2006-RELEASE/lib/org.apache.xerces.impl_2.11.0.jar!/org/apache/xerces/jaxp/DocumentBuilderFactoryImpl.class

This proves that Katalon Studio 8.0.1 bundles the org.apache.xerces.impl_2.11.0.jar; which was released Feb, 2013.

According to this post on Stackoverflow,

Apache Xerces-J 2.12.0 and earlier implement older versions of JAXP that do not support either of the properties that you are trying to set.

My conclusion

So, I guess Katalon Team has made a mistake at v8.0.1, at com.kms.katalon.util.DocumentBuilderProvider class. Due to it, Katalon Studio v8.0.x can not process SOAP request/response messages and other XML documents appropriately.

But, if user’s Test Case and Keywords process XML documents without calling the problematic com.kms.katalon.util.DocumentBuilderProvider class, it will work fine.

-> @ThanhTo, @duyluong

2 Likes

Using v7.9.1, I checked if this class is available or not. See the following screenshot.

This check proved that the com.kms.katalon.util.DocumentBuilderProvider was newly introduced as of v8.0.x. This is the reason why we see the IllegalArgumentException in the v8.0.1 and do not see it in the v7.9.1.

@duyluong

as Chrome: saving an xml file instead of displaying it tells, some KS users are trapped by this problem.

Are you going to fix this? In other words, are you going to upgrade the version of Apache Xerces-J > 2.12.0 ?

HI @kazurayam,

This issue already fixed in v8.0.5 (the latest version). Sorry for we didn’t announce earlier.

We used this solution instead of upgrading Apache Xerces to v2.12.0. Apache Xerces is also a dependency of another Katalon Studio component (not only WebService) so we need time to evaluate about the upgrade.

This description is not clear enough for users what to do.

In v8.0.5, I ran the following testcase A:

// Test Case A
import javax.xml.parsers.DocumentBuilder
import javax.xml.parsers.DocumentBuilderFactory

/*
System.setProperty("javax.xml.parsers.DocumentBuilderFactory",
	"com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");
*/

DocumentBuilder parser = newBuilderInstance()

DocumentBuilder newBuilderInstance() {
	DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance()
	println "This DocumentBuilderFactory is an instance of " + dbFactory.getClass().getName()
	dbFactory.setAttribute("http://javax.xml.XMLConstants/property/accessExternalDTD","")
	dbFactory.setAttribute("http://javax.xml.XMLConstants/property/accessExternalSchema","")
	return dbFactory.newDocumentBuilder()
}

When I ran the Test Case A I got an exception:

This DocumentBuilderFactory is an instance of org.apache.xerces.jaxp.DocumentBuilderFactoryImpl
...
2021-08-11 11:00:02.352 ERROR c.k.katalon.core.main.TestCaseExecutor   - ❌ Test Cases/reproducingAccessExternalDTDproblem FAILED.
Reason:
java.lang.IllegalArgumentException: Property 'http://javax.xml.XMLConstants/property/accessExternalDTD' is not recognized.


This is not good, obviously.

So I changed it slightly as your solution tells us to do. I got the following Test Case B.

// Test Case B
import javax.xml.parsers.DocumentBuilder
import javax.xml.parsers.DocumentBuilderFactory

System.setProperty("javax.xml.parsers.DocumentBuilderFactory",
	"com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");

DocumentBuilder parser = newBuilderInstance()

DocumentBuilder newBuilderInstance() {
	DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance()
	println "This DocumentBuilderFactory is an instance of " + dbFactory.getClass().getName()
	dbFactory.setAttribute("http://javax.xml.XMLConstants/property/accessExternalDTD","")
	dbFactory.setAttribute("http://javax.xml.XMLConstants/property/accessExternalSchema","")
	return dbFactory.newDocumentBuilder()
}

Test Case B worked fine. No exception was thrown. In the console I saw:

This DocumentBuilderFactory is an instance of com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl


@duylong,

Do you want us repeat writing our test cases so that they have the line of

System.setProperty("javax.xml.parsers.DocumentBuilderFactory",
    "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");

in all Test Cases if we are going to process XML document as of v8.0.x? Do you mean it is “a satisfactory fix” done in v8.0.5?

To me, this looks not a “fix”. This is a workaround.

Still it is good to have a workaround for a known problem. If you want users to follow this workaround, then you should write a new page in the official document and explain what users should do clearly.

I recreated a sample Katalong Studio project : SimplestSOAP-API-Test.zip (57.3 KB)

This includes

  • Test Cases/CalculatorTest — this will fail due to an Exception about “accessExternalDTD”
  • Test Cases/CalculatorWithWorkaroundTest — this will run OK, no Exception thrown.

@duyluong

Do you want us write our test cases as the “CalculatorWithWorkaroundTest” ?

@kazurayam,

Sorry for my mistake,

This issue will be fixed in v8.1.0. v8.0.5 doesn’t include the fix.
In v8.1.0, you don’t need to use the workaround in CalculatorWithWorkaroundTest and the test case CalculatorTest will run OK.

For now, you can try v8.1.0.beta at https://github.com/katalon-studio/katalon-studio/releases/tag/v8.1.0.beta

Thank you for the info.

I checked v8.1.0.beta and found the problem is fixed in that version.