Oracle读取xmltype依赖包xmlparserv2导致spring xml读取报错

原创
06/15 16:50
阅读数 122

异常内容

Caused by: org.xml.sax.SAXParseException: <Line 10, Column 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:00 INFO  com.gongstring.SampleAppStarter [651] - No active profile set, falling back to default profiles: default

<Line 43, Column 57>: XML-24509: (Error) Duplicated definition for: 'identifiedType'
<Line 61, Column 28>: XML-24509: (Error) Duplicated definition for: 'beans'
<Line 182, Column 34>: XML-24509: (Error) Duplicated definition for: 'description'
<Line 194, Column 29>: XML-24509: (Error) Duplicated definition for: 'import'
<Line 216, Column 28>: XML-24509: (Error) Duplicated definition for: 'alias'
<Line 245, Column 33>: XML-24509: (Error) Duplicated definition for: 'beanElements'
<Line 260, Column 44>: XML-24509: (Error) Duplicated definition for: 'beanAttributes'
<Line 515, Column 43>: XML-24509: (Error) Duplicated definition for: 'meta'
<Line 523, Column 35>: XML-24509: (Error) Duplicated definition for: 'metaType'
<Line 540, Column 27>: XML-24509: (Error) Duplicated definition for: 'bean'
<Line 560, Column 38>: XML-24509: (Error) Duplicated definition for: 'constructor-arg'
<Line 639, Column 51>: XML-24509: (Error) Duplicated definition for: 'property'
<Line 650, Column 32>: XML-24509: (Error) Duplicated definition for: 'qualifier'
<Line 666, Column 48>: XML-24509: (Error) Duplicated definition for: 'attribute'
<Line 676, Column 36>: XML-24509: (Error) Duplicated definition for: 'lookup-method'
<Line 718, Column 38>: XML-24509: (Error) Duplicated definition for: 'replaced-method'
<Line 755, Column 31>: XML-24509: (Error) Duplicated definition for: 'arg-type'
<Line 782, Column 26>: XML-24509: (Error) Duplicated definition for: 'ref'
<Line 811, Column 28>: XML-24509: (Error) Duplicated definition for: 'idref'
<Line 836, Column 28>: XML-24509: (Error) Duplicated definition for: 'value'
<Line 864, Column 27>: XML-24509: (Error) Duplicated definition for: 'null'
<Line 878, Column 39>: XML-24509: (Error) Duplicated definition for: 'collectionElements'
<Line 897, Column 28>: XML-24509: (Error) Duplicated definition for: 'array'
<Line 920, Column 27>: XML-24509: (Error) Duplicated definition for: 'list'
<Line 943, Column 26>: XML-24509: (Error) Duplicated definition for: 'set'
<Line 964, Column 26>: XML-24509: (Error) Duplicated definition for: 'map'
<Line 985, Column 45>: XML-24509: (Error) Duplicated definition for: 'entry'
<Line 994, Column 28>: XML-24509: (Error) Duplicated definition for: 'props'
<Line 1016, Column 26>: XML-24509: (Error) Duplicated definition for: 'key'
<Line 1027, Column 27>: XML-24509: (Error) Duplicated definition for: 'prop'
<Line 1046, Column 39>: XML-24509: (Error) Duplicated definition for: 'propertyType'
<Line 1090, Column 41>: XML-24509: (Error) Duplicated definition for: 'collectionType'
<Line 1102, Column 40>: XML-24509: (Error) Duplicated definition for: 'listOrSetType'
<Line 1111, Column 34>: XML-24509: (Error) Duplicated definition for: 'mapType'
<Line 1133, Column 36>: XML-24509: (Error) Duplicated definition for: 'entryType'
<Line 1180, Column 36>: XML-24509: (Error) Duplicated definition for: 'propsType'
<Line 1193, Column 45>: 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; <Line 10, Column 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; <Line 10, Column 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: <Line 10, Column 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 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: <Line 10, Column 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.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) **

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.

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部