gongstring技术博客
最新文章
源码解读
软件安装
常见问题
大数据
常用工具
鸡汤文
备案号:鄂ICP备15015839号-1
鄂公网安备 42010202001692号
Oracle读取xmltype依赖包xmlparserv2导致spring xml读取报错
2020-06-15 16:24:10
作者: gongstring
常见问题
/
Oracle读取xmltype依赖包xmlparserv2导致spring xml读取报错
## 异常内容 ``` Caused by: org.xml.sax.SAXParseException:
: XML-24500: (Error) Can not build schema 'http://www.springframework.org/schema/context' located at 'http://www.springframework.org/schema/context/spring-context.xsd' ``` ``` [] 16:26:00 INFO com.gongstring.SampleAppStarter [651] - No active profile set, falling back to default profiles: default
: XML-24509: (Error) Duplicated definition for: 'identifiedType'
: XML-24509: (Error) Duplicated definition for: 'beans'
: XML-24509: (Error) Duplicated definition for: 'description'
: XML-24509: (Error) Duplicated definition for: 'import'
: XML-24509: (Error) Duplicated definition for: 'alias'
: XML-24509: (Error) Duplicated definition for: 'beanElements'
: XML-24509: (Error) Duplicated definition for: 'beanAttributes'
: XML-24509: (Error) Duplicated definition for: 'meta'
: XML-24509: (Error) Duplicated definition for: 'metaType'
: XML-24509: (Error) Duplicated definition for: 'bean'
: XML-24509: (Error) Duplicated definition for: 'constructor-arg'
: XML-24509: (Error) Duplicated definition for: 'property'
: XML-24509: (Error) Duplicated definition for: 'qualifier'
: XML-24509: (Error) Duplicated definition for: 'attribute'
: XML-24509: (Error) Duplicated definition for: 'lookup-method'
: XML-24509: (Error) Duplicated definition for: 'replaced-method'
: XML-24509: (Error) Duplicated definition for: 'arg-type'
: XML-24509: (Error) Duplicated definition for: 'ref'
: XML-24509: (Error) Duplicated definition for: 'idref'
: XML-24509: (Error) Duplicated definition for: 'value'
: XML-24509: (Error) Duplicated definition for: 'null'
: XML-24509: (Error) Duplicated definition for: 'collectionElements'
: XML-24509: (Error) Duplicated definition for: 'array'
: XML-24509: (Error) Duplicated definition for: 'list'
: XML-24509: (Error) Duplicated definition for: 'set'
: XML-24509: (Error) Duplicated definition for: 'map'
: XML-24509: (Error) Duplicated definition for: 'entry'
: XML-24509: (Error) Duplicated definition for: 'props'
: XML-24509: (Error) Duplicated definition for: 'key'
: XML-24509: (Error) Duplicated definition for: 'prop'
: XML-24509: (Error) Duplicated definition for: 'propertyType'
: XML-24509: (Error) Duplicated definition for: 'collectionType'
: XML-24509: (Error) Duplicated definition for: 'listOrSetType'
: XML-24509: (Error) Duplicated definition for: 'mapType'
: XML-24509: (Error) Duplicated definition for: 'entryType'
: XML-24509: (Error) Duplicated definition for: 'propsType'
: XML-24509: (Error) Duplicated definition for: 'defaultable-boolean' [] 16:26:01 WARN org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext [558] - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 10 in XML document from class path resource [spring/spring-base.xml] is invalid; nested exception is org.xml.sax.SAXParseException; lineNumber: 10; columnNumber: 103;
: XML-24500: (Error) Can not build schema 'http://www.springframework.org/schema/context' located at 'http://www.springframework.org/schema/context/spring-context.xsd' [] 16:26:01 INFO org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener [136] - Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled. [] 16:26:01 ERROR org.springframework.boot.SpringApplication [826] - Application run failed org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 10 in XML document from class path resource [spring/spring-base.xml] is invalid; nested exception is org.xml.sax.SAXParseException; lineNumber: 10; columnNumber: 103;
: XML-24500: (Error) Can not build schema 'http://www.springframework.org/schema/context' located at 'http://www.springframework.org/schema/context/spring-context.xsd' at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:402) at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:338) at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:310) at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:188) at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:224) at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:195) at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.lambda$loadBeanDefinitionsFromImportedResources$0(ConfigurationClassBeanDefinitionReader.java:378) at java.util.LinkedHashMap.forEach(LinkedHashMap.java:684) at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsFromImportedResources(ConfigurationClassBeanDefinitionReader.java:345) at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:147) at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:120) at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:331) at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:236) at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:280) at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:96) at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:706) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:532) at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) at com.gongstring.SampleAppStarter.main(SampleAppStarter.java:13) Caused by: org.xml.sax.SAXParseException:
: XML-24500: (Error) Can not build schema 'http://www.springframework.org/schema/context' located at 'http://www.springframework.org/schema/context/spring-context.xsd' at oracle.xml.parser.v2.XMLError.flushErrorHandler(XMLError.java:428) at oracle.xml.parser.v2.XMLError.flushErrors1(XMLError.java:290) at oracle.xml.parser.v2.NonValidatingParser.parseDocument(NonValidatingParser.java:438) at oracle.xml.parser.v2.XMLParser.parse(XMLParser.java:251) at oracle.xml.jaxp.JXDocumentBuilder.parse(JXDocumentBuilder.java:175) Caused by: org.xml.sax.SAXParseException:
: XML-24500: (Error) Can not build schema 'http://www.springframework.org/schema/context' located at 'http://www.springframework.org/schema/context/spring-context.xsd' at org.springframework.beans.factory.xml.DefaultDocumentLoader.loadDocument(DefaultDocumentLoader.java:77) at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadDocument(XmlBeanDefinitionReader.java:432) at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:390) ... 23 common frames omitted Caused by: oracle.xml.parser.schema.XSDException: Duplicated definition for: 'identifiedType' Caused by: oracle.xml.parser.schema.XSDException: Duplicated definition for: 'identifiedType' at oracle.xml.parser.schema.XSDBuilder.buildSchema(XSDBuilder.java:1127) at oracle.xml.parser.schema.XSDBuilder.build(XSDBuilder.java:678) at oracle.xml.parser.schema.XSDValidator.processSchemaLocation(XSDValidator.java:1063) at oracle.xml.parser.schema.XSDValidator.startElement(XSDValidator.java:668) at oracle.xml.parser.v2.NonValidatingParser.parseElement(NonValidatingParser.java:1648) at oracle.xml.parser.v2.NonValidatingParser.parseRootElement(NonValidatingParser.java:471) at oracle.xml.parser.v2.NonValidatingParser.parseDocument(NonValidatingParser.java:417) ... 28 common frames omitted > Task :gongstring-component-sample:SampleAppStarter.main() FAILED ``` ## 初步分析 由于在项目中需要解析Oracle的XmlType字段,所以除了引入odjbc8.jar外,还要引入如下包:orai18n.jar、xdb6.jar、xmlparserv2.jar(这些包可以从oracle安装文件中找得到)。 其中xmlparserv2.jar的引入会导致容器在加载Spring的xml文件时候出现报错。 ## 解决办法 官方回复:https://forums.oracle.com/forums/thread.jspa?threadID=1078787 下面是节选的部分回复: Newbie f7601bf8-8486-4551-9722-7195adfbf42c Aug 16, 2013 9:52 PM (in response to 407022) I ran into this exact issue while trying to get hibernate and spring working with an oracle XMLType column, and found a better solution than to use JVM arguments as you mentioned. ** Why is it happening? ** The xmlparserv2.jar uses the JAR Services API (Service Provider Mechanism) to change the default javax.xml classes used for the SAXParserFactory, DocumentBuilderFactory and TransformerFactory. ** How did it happen? ** * 简单释义:因为xmlparserv2.jar中存在META-INF/services目录,里面有制定几个XML解析需要的关键配置,这些配置使用的是oracle特有的,而不是JDK中提供的。 The javax.xml.parsers.FactoryFinder looks for custom implementations by checking for, in this order, environment variables, %JAVA_HOME%/lib/jaxp.properties, then for config files under META-INF/services on the classpath, before using the default implementations included with the JDK (com.sun.org.*). Inside xmlparserv2.jar exists a META-INF/services directory, which the javax.xml.parsers.FactoryFinder class picks up and uses: META-INF/services/javax.xml.parsers.DocumentBuilderFactory (which defines oracle.xml.jaxp.JXDocumentBuilderFactory as the default) META-INF/services/javax.xml.parsers.SAXParserFactory (which defines oracle.xml.jaxp.JXSAXParserFactory as the default) META-INF/services/javax.xml.transform.TransformerFactory (which defines oracle.xml.jaxp.JXSAXTransformerFactory as the default) ** Solution? ** Switch all 3 back, otherwise you'll see weird errors. javax.xml.parsers.* fix the visible errors, while the javax.xml.transform.* fixes more subtle XML parsing (in my case, with apache commons configuration reading/writing). QUICK SOLUTION to solve the application server startup errors: ** JVM Arguments (not great) ** * 方法一:在JVM启动的时候,通过-D参数强制制定参数值为JDK提供的实现,但是在使用JUnit的RunWith进行单元测试的时候,还是会出现异常,就需要在@BeforeClass中通过System.setProperties方法指定 To override the changes made by xmlparserv2.jar, add the following JVM properties to your application server startup arguments. The java.xml.parsers.FactoryFinder logic will check environment variables first. ``` -Djavax.xml.parsers.SAXParserFactory=com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl -Djavax.xml.parsers.DocumentBuilderFactory=com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl -Djavax.xml.transform.TransformerFactory=com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl ``` However, if you run test cases using @RunWith(SpringJUnit4ClassRunner.class) or similar, you will still experience the error. BETTER SOLUTION to the application server startup errors AND test case errors: Option 1: Use JVM arguments for the app server and @BeforeClass statements for your test cases. ``` System.setProperty("javax.xml.parsers.DocumentBuilderFactory","com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl"); System.setProperty("javax.xml.parsers.SAXParserFactory","com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl"); System.setProperty("javax.xml.transform.TransformerFactory","com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl"); ``` If you have a lot of test cases, this becomes painful. * 方法二(推荐):可以在自己的项目中,添加自定义配置,用于覆盖xmlparserv2.jar里面的配置信息。在自己项目的resources中添加目录(/META-INF/services),并添加下面几个文件 ``` 文件一:javax.xml.parsers.DocumentBuilderFactory 内容: com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl 文件二:javax.xml.parsers.SAXParserFactory 内容:com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl 文件三:javax.xml.transform.TransformerFactory 内容:com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl ``` Option 2: Create your own Service Provider definition files in the compile/runtime classpath for your project, which will override those included in xmlparserv2.jar. ``` In a maven spring project, override the xmlparserv2.jar settings by creating the following files in the %PROJECT_HOME%/src/main/resources directory: %PROJECT_HOME%/src/main/resources/META-INF/services/javax.xml.parsers.DocumentBuilderFactory (which defines com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl as the default) %PROJECT_HOME%/src/main/resources/META-INF/services/javax.xml.parsers.SAXParserFactory (which defines com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl as the default) %PROJECT_HOME%/src/main/resources/META-INF/services/javax.xml.transform.TransformerFactory (which defines com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl as the default) ``` These files are referenced by both the application server (no JVM arguments required), and solves any unit test issues without requiring any code changes. ```