Affects: 5.3.9
(and earlier versions)
Operating system: z/OS 2.3
Java version:
Java(TM) SE Runtime Environment (build 8.0.6.26 - pmz6480sr6fp26-20210226_01(SR6 FP26))
IBM J9 VM (build 2.9, JRE 1.8.0 z/OS s390x-64-Bit Compressed References 20210216_465732 (JIT enabled, AOT enabled)
OpenJ9 - e5f4f96
OMR - 999051a
IBM - 358762e)
JCL - 20210108_01 based on Oracle jdk8u281-b09
When loading SQL error codes from sql-error-codes.xml on a z/OS system, the following exception is thrown:
org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 15 in XML document from class path resource [org/springframework/jdbc/support/sql-error-codes.xml] is invalid; nested exception is org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'beans'.
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:402) ~[spring-beans-5.3.9.jar!/:5.3.9]
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:338) ~[spring-beans-5.3.9.jar!/:5.3.9]
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:310) ~[spring-beans-5.3.9.jar!/:5.3.9]
at org.springframework.jdbc.support.SQLErrorCodesFactory.<init>(SQLErrorCodesFactory.java:114) [spring-jdbc-5.3.9.jar!/:5.3.9]
at org.springframework.jdbc.support.SQLErrorCodesFactory.<clinit>(SQLErrorCodesFactory.java:72) [spring-jdbc-5.3.9.jar!/:5.3.9]
at de.ralphriedel.Application.run(Application.java:17) [classes!/:na]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:791) [spring-boot-2.5.3.jar!/:2.5.3]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:775) [spring-boot-2.5.3.jar!/:2.5.3]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:345) [spring-boot-2.5.3.jar!/:2.5.3]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343) [spring-boot-2.5.3.jar!/:2.5.3]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1332) [spring-boot-2.5.3.jar!/:2.5.3]
at de.ralphriedel.Application.main(Application.java:13) [classes!/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:90) ~[na:1.8.0]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55) ~[na:1.8.0]
at java.lang.reflect.Method.invoke(Method.java:508) ~[na:1.8.0]
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49) [spring-zos-dtd-issue-0.0.1-SNAPSHOT.jar:na]
at org.springframework.boot.loader.Launcher.launch(Launcher.java:108) [spring-zos-dtd-issue-0.0.1-SNAPSHOT.jar:na]
at org.springframework.boot.loader.Launcher.launch(Launcher.java:58) [spring-zos-dtd-issue-0.0.1-SNAPSHOT.jar:na]
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:88) [spring-zos-dtd-issue-0.0.1-SNAPSHOT.jar:na]
Caused by: org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'beans'.
at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source) ~[na:na]
at org.apache.xerces.util.ErrorHandlerWrapper.error(Unknown Source) ~[na:na]
at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source) ~[na:na]
at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source) ~[na:na]
at org.apache.xerces.impl.xs.XMLSchemaValidator.handleStartElement(Unknown Source) ~[na:na]
at org.apache.xerces.impl.xs.XMLSchemaValidator.startElement(Unknown Source) ~[na:na]
at org.apache.xerces.impl.dtd.XMLDTDValidator.startElement(Unknown Source) ~[na:na]
at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source) ~[na:na]
at org.apache.xerces.impl.XMLNSDocumentScannerImpl$NSContentDispatcher.scanRootElementHook(Unknown Source) ~[na:na]
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source) ~[na:na]
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source) ~[na:na]
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source) ~[na:na]
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source) ~[na:na]
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source) ~[na:na]
at org.apache.xerces.parsers.DOMParser.parse(Unknown Source) ~[na:na]
at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source) ~[na:na]
at org.springframework.beans.factory.xml.DefaultDocumentLoader.loadDocument(DefaultDocumentLoader.java:77) ~[spring-beans-5.3.9.jar!/:5.3.9]
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadDocument(XmlBeanDefinitionReader.java:432) ~[spring-beans-5.3.9.jar!/:5.3.9]
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:390) ~[spring-beans-5.3.9.jar!/:5.3.9]
... 19 common frames omitted
This can be reproduced trivially by getting the error codes for any given database from an instance of SQLErrorCodesFactory
:
SQLErrorCodesFactory.getInstance().getErrorCodes("DB2")
I have also created a small sample project that does just that in a personal repo.
The problem seems to occur only on z/OS, my tests on Windows or Linux have resulted in no such behavior. In addition to the admittedly rather exotic platform, the system encoding is an EBCDIC flavor (IBM-1047). Could this cause an issue when the DTD gets read from the classpath?
In any case, since the issue seems with parsing the beans DTD, I replaced the DTD definition with the equivalent XML Schema definition and found that this way, it works fine. Given that XML Schema-based configuration has been the preferred way of doing things for a while, would the Spring team accept a PR that replaces the beans DTD with the appropriate XML Schema definition in sql-error-codes.xml
? If so, I would be happy to submit one to side-step this issue.
Comment From: snicoll
@ralph-riedel sorry it took so long to process this one. Are you still willing to contribute?
Comment From: ralph-riedel
I'd be thrilled to help if I can. It's been a while, so I'd have to look at the specifics of this issue again but I'm sure I'll manage. So would you like a PR for replacing the beans DTD?
Comment From: snicoll
Yes please.
Comment From: bclozel
Closing in favor of #31354