問題描述
項目依賴源碼打包的時候,會報dubbo.xsd找不到的問題。http://code.alibabatech.com/schema/dubbo/dubbo.xsd讀取不到
目錄結構
- dubbo-demo-provider.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- provider's application name, used for tracing dependency relationship -->
<dubbo:application name="demo-provider"/>
<!--<dubbo:monitor protocol="registry"></dubbo:monitor>-->
<!-- use multicast registry center to export service -->
<!--<dubbo:registry address="multicast://224.5.6.7:1234"/>-->
<!--訂閱并注冊在zk上-->
<dubbo:registry id="aliZk" protocol="zookeeper" address="47.94.102.25:2181"/>
<dubbo:registry id="vmZk" protocol="zookeeper" address="192.168.0.100:2181" check="false" />
<!-- use dubbo protocol to export service on port 20880 -->
<!--配置線程模式-->
<dubbo:protocol id="dubbo1" name="dubbo" port="20881" dispatcher="execution" threadpool="cached" threads="5"/>
<dubbo:protocol id="dubbo2" name="dubbo" port="20882" dispatcher="execution" threadpool="cached" threads="5"/>
<!-- service implementation, as same as regular local bean -->
<bean id="demoService" class="com.alibaba.dubbo.demo.provider.DemoServiceImpl"/>
<!-- declare the service interface to be exported -->
<dubbo:service interface="com.alibaba.dubbo.demo.DemoService" ref="demoService" protocol="dubbo1,dubbo2" registry="aliZk"/>
</beans>
重現(xiàn)
- 使用如下pom.xml打包
<build>
<finalName>mydubbo-server</finalName>
<resources>
<resource>
<targetPath>${project.build.directory}/classes</targetPath>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
<!-- 結合com.alibaba.dubbo.container.Main -->
<resource>
<targetPath>${project.build.directory}/classes/META-INF/spring</targetPath>
<directory>src/main/resources/spring</directory>
<filtering>true</filtering>
<includes>
<include>spring-context.xml</include>
</includes>
</resource>
</resources>
<plugins>
<!-- 打包jar文件時,配置manifest文件,加入lib包的jar依賴 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<classesDirectory>target/classes/</classesDirectory>
<archive>
<manifest>
<mainClass>com.alibaba.dubbo.container.Main</mainClass>
<!-- 打包時 MANIFEST.MF文件不記錄的時間戳版本 -->
<useUniqueVersions>false</useUniqueVersions>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
<manifestEntries>
<Class-Path>.</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<type>jar</type>
<includeTypes>jar</includeTypes>
<useUniqueVersions>false</useUniqueVersions>
<outputDirectory>
${project.build.directory}/lib
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
- 執(zhí)行構建
mvn clean install
- 構建結果:將mydubbo-server.jar和lib目錄拷貝到指定的目錄下,命令行運行
java -jar mydubbo-server.jar
就可以運行dubbo服務了。(注:lib目錄下的所有jar包是mydubbo-server.jar的依賴jar)
執(zhí)行jar文件
E:\dubbo\incubator-dubbo\dubbo-demo\dubbo-demo-provider\target> java -jar .\mydubbo-server.jar
出現(xiàn)異常
[07/06/18 11:25:35:035 CST] main WARN xml.XmlBeanDefinitionReader: Ignored XML validation warning
org.xml.sax.SAXParseException; lineNumber: 24; columnNumber: 46; schema_reference.4: 無法讀取方案文檔 'http://code.alibabatech.com/schema/dubbo/dubbo.xsd', 原因為 1) 無法找到文檔; 2) 無法讀取文檔; 3) 文檔的 根元素不是 <xsd:schema>。
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.warning(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.reportSchemaErr(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.reportSchemaWarning(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.getSchemaDocument1(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.getSchemaDocument(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.parseSchema(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadSchema(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.findSchemaGrammar(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleStartElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.emptyElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source)
at org.springframework.beans.factory.xml.DefaultDocumentLoader.loadDocument(DefaultDocumentLoader.java:76)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadDocument(XmlBeanDefinitionReader.java:429)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:391)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:336)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:304)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:181)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:217)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:188)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:252)
at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:127)
at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:93)
at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:129)
at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:614)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:515)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:93)
at com.alibaba.dubbo.container.spring.SpringContainer.start(SpringContainer.java:45)
at com.alibaba.dubbo.container.Main.main(Main.java:85)
原因分析
dubbo
的標簽都是通過spring.handler
文件中配置的對應的namespaceHandler
解析,解析時還會去加載http\://code.alibabatech.com/schema/dubbo/dubbo.xsd
指向的xsd文件,這個映射是在dubbo的spring.schemas
中配置的。由于我們使用的是源碼構建的,dubbo的spring.schemas
文件是在dubbo-config-spring-2.6.1.jar
里(路徑dubbo-config-spring-2.6.1.jar\META-INF\spring.schemas
,內容是http\://code.alibabatech.com/schema/dubbo/dubbo.xsd=META-INF/dubbo.xsd
),
但是spring
并不知道這個路徑下還有spring.schemas
,也就無法加載http\://code.alibabatech.com/schema/dubbo/dubbo.xsd
指向的xsd文件,所以spring會報加載不到*.xsd文件的異常。
解決方案
現(xiàn)在的解決方案是將所有的spring.schemas合并在一起,而不用去加載單個jar里面的映射文件。所以我們使用maven的shade插件將所有jar里的spring.schemas文件進行合并,在最終生成的單一jar包里,spring.schemas包含了所有出現(xiàn)過的映射
- pom.xml中新增shade插件
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<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.schemas</resource>
</transformer>
<!--<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/com.alibaba.dubbo.rpc.Protocol</resource>
</transformer>-->
<!--<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.alibaba.dubbo.demo.provider.Provider</mainClass>
</transformer>-->
</transformers>
</configuration>
</execution>
</executions>
</plugin>
-
打包結果
mydubbo-server.jar\META-INF 查看合并后的文件
mydubbo-server.jar\META-INF\spring.schemas
...
http\://www.springframework.org/schema/aop/spring-aop-2.0.xsd=org/springframework/aop/config/spring-aop-2.0.xsd
http\://www.springframework.org/schema/aop/spring-aop-2.5.xsd=org/springframework/aop/config/spring-aop-2.5.xsd
http\://www.springframework.org/schema/aop/spring-aop-3.0.xsd=org/springframework/aop/config/spring-aop-3.0.xsd
http\://www.springframework.org/schema/aop/spring-aop-3.1.xsd=org/springframework/aop/config/spring-aop-3.1.xsd
http\://www.springframework.org/schema/aop/spring-aop-3.2.xsd=org/springframework/aop/config/spring-aop-3.2.xsd
http\://www.springframework.org/schema/aop/spring-aop-4.0.xsd=org/springframework/aop/config/spring-aop-4.0.xsd
http\://www.springframework.org/schema/aop/spring-aop-4.1.xsd=org/springframework/aop/config/spring-aop-4.1.xsd
http\://www.springframework.org/schema/aop/spring-aop-4.2.xsd=org/springframework/aop/config/spring-aop-4.2.xsd
http\://www.springframework.org/schema/aop/spring-aop-4.3.xsd=org/springframework/aop/config/spring-aop-4.3.xsd
http\://www.springframework.org/schema/aop/spring-aop.xsd=org/springframework/aop/config/spring-aop-4.3.xsd
http\://code.alibabatech.com/schema/dubbo/dubbo.xsd=META-INF/dubbo.xsd
...
- 運行成功
java -jar mydubbo-server.jar
[07/06/18 01:28:29:029 CST] main DEBUG env.PropertySourcesPropertyResolver: Could not find key 'spring.liveBeansView.mbeanDomain' in any property source
[07/06/18 01:28:29:029 CST] main DEBUG support.DefaultListableBeanFactory: Returning cached instance of singleton bean 'lifecycleProcessor'
[07/06/18 01:28:29:029 CST] main INFO container.Main: [DUBBO] Dubbo SpringContainer started!, dubbo version: 2.6.1, current host: 192.168.0.1
[2018-06-07 13:28:29] Dubbo service server started!