被這個問題折磨着很久:參考: http://have23.iteye.com/blog/1340777
(cfx 與 spring 整合的時候出現的問題:
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://cxf.apache.org/jaxws]
Offending resource: ServletContext resource [/WEB-INF/spring.xml]
)
Key Words
Spring 3.0
Apache CXF 2.X.X
昨日,在原本應用中添加了關於webService的調用,使用了Apache CXF 框架,並將其集成到了Spring中。
當時集成時,使用了如下的jar包(Spring2.5.5.JPG)

加入CXF的相關jar包

然后將WebService客戶端集成到Spring中,代碼類似於:
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:jaxws="http://cxf.apache.org/jaxws"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
- http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
- <jaxws:client id="helloClient"
- serviceClass="demo.spring.HelloWorld"
- address="http://localhost:9002/HelloWorld" />
- </beans>
然后在Myeclipse 8.5上進行了測試,運行通過。
然后通過Fat jar打成jar包進行發布。對,這不是一個web應用。
到了實際部署環境,剛運行就出現:
org.xml.sax.SAXParseException: schema_reference.4: Failed to read schema document 'http://www.springframework.org/schema/beans/spring-beans-2.5.xsd', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>.
出現這個錯。我的第一判斷是jar有沖突。你懂的
於是,我從早上11點到下午5點,來解決這個jar包沖突的問題,做了一下的工作
1.從Spring2.5.5 換到Spring.3.0.5
2.將CXF2.3.1換到CXF2.5.1
最終的結果是:蛋都碎了。。。
而且還出現了新的問題:
org.xml.sax.SAXParseException: schema_reference.4: Failed to read schema document 'http://www.springframework.org/schema/beans/spring-beans-3.0.xsd', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>.
org.xml.sax.SAXParseException: schema_reference.4: Failed to read schema document 'http://cxf.apache.org/schema/jaxws.xsd', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>.
終於意識到,不是jar包的問題。而是SAXParse沒有正常工作。於是去網上轉了一圈,有如下結果
“What IDE (if any) are you using? Does this happen when you're working within an IDE, or only on deployment? If it's deployment, it might be because whatever mechanism of deployment you use -- maven-assembly making a single JAR with dependencies is a known culprit -- is collapsing all your JARs into a single directory and the Spring schema and handler files are overwriting each other.”
我英文一般的很,這段話大概的意思就是
使用maven-assembly 插件壓縮的all your jars到一個單一目錄,並且Spring schema and handler files互相覆蓋。
可惜,我沒有使用maven。Spring schema and handler files 是什么
Spring步入到3.0后,出現了一些顯著的變化就是沒有提供spring.jar了,而采用了不同功能的jar

而幾乎每個jar包中都存在

這就是導致出現
Unable to locate Spring NamespaceHandler for XML schema namespace的問題。
接下來,你可以參考
http://stackoverflow.com/questions/3650252/problem-starting-spring-application-from-java
你可以選擇手工合並所有的spring.handlers與spring.schemas,或者和我一樣換回到Spring 2.5,並將cxf2.x.x.jar中的這兩個文件重新命名,然后不使用Spring集成,先讓程序跑起來不影響業務。
參考
https://jira.springsource.org/browse/SPR-8368
這里面說的更加詳細一些
With the splitting of Spring Framework into multiple jar files in v3.0, there are now several files named "META-INF/spring.handlers", "spring.schemas" and "spring.tooling". This is not a problem when running in a normal servlet container, but poses problems when e.g. creating an executable JAR file from a webapp using an embedded web server such as Jetty, or running GWT in "Dev Mode", which uses a custom class loader.
The workaround is to construct your own "custom" version of these three files, merging all the copies into one like so:
//IOUtils and FileUtils come from Apache Commons IOfor(String s : new String[] {"spring.schemas", "spring.handlers", "spring.tooling"}) {
Enumeration<?> e = Test.class.getClassLoader().getResources("META-INF/"+s);
StringBuilder out = new StringBuilder();while(e.hasMoreElements()) { URL u = (URL) e.nextElement(); out.append(IOUtils.toString(u.openStream())).append("\n"); }
File outf = new File(s);
FileUtils.writeStringToFile(outf, out.toString(), "UTF-8");
}
However, the proper fix would be to use a different file-name for each instance of the schemas/handlers/tooling files. For example, inside "org.springframework.aop-3.0.5.RELEASE.jar/META-INF" you would find "spring-aop.schemas", "spring-aop.handlers" and "spring-aop.tooling".
I'm afraid I'm not sufficiently up-to-speed with the Spring code-base to give you a patch to do this, however a brief investigation shows that "spring.handlers" and "spring.schemas" are specified in org.springframework.beans.factory.xml.PluggableSchemaResolver and DefaultNamespaceHandlerResolver, and that constructors exist for specifying different locations for these files. I hope you find this information useful.
或許這個已經在新版本里面已經fixed了,我已經下了最新的版本,還沒有來得及測試。
如果你也遇到這個問題,首先恭喜你。
其次,你可以按照以上的方式做一個 “your own "custom" version of these three files”,使用
- //IOUtils and FileUtils come from Apache Commons IOfor(String s : new String[] {"spring.schemas", "spring.handlers", "spring.tooling"}) {
- Enumeration<?> e = Test.class.getClassLoader().getResources("META-INF/"+s);
- StringBuilder out = new StringBuilder();while(e.hasMoreElements()) { URL u = (URL) e.nextElement(); out.append(IOUtils.toString(u.openStream())).append("\n"); }
- File outf = new File(s);
- FileUtils.writeStringToFile(outf, out.toString(), "UTF-8");
- }
合並文件以后,來代替jar包中\META-INF\spring.schemas,\META-INF\spring.handlers,
\META-INF\spring.tooling,就可以了.
最好的辦法是通過maven去打包在POM.xml中增加
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-shade-plugin</artifactId>
- <version>1.6</version>
- <configuration>
- <!-- put your configurations here -->
- </configuration>
- <executions>
- <execution>
- <phase>package</phase>
- <goals>
- <goal>shade</goal>
- </goals>
- <configuration>
- <transformers>
- <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
- <manifestEntries>
- <Main-Class>util.Process</Main-Class>
- </manifestEntries>
- </transformer>
- <transformer
- implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
- <resource>META-INF/cxf/bus-extensions.txt</resource>
- </transformer>
- <transformer
- implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
- <resource>META-INF/spring.handlers</resource>
- </transformer>
- <transformer
- implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
- <resource>META-INF/spring.tooling</resource>
- </transformer>
- <transformer
- implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
- <resource>META-INF/spring.schemas</resource>
- </transformer>
- </transformers>
- </configuration>
- </execution>
- </executions>
- </plugin>
來合並這些文件,來保證在打包時這些文件不會互相覆蓋。

