问题描述
项目依赖源码打包的时候,会报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>
重现
- 使用如下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>
- 执行构建
mvn clean install
- 构建结果:将mydubbo-server.jar和lib目录拷贝到指定的目录下,命令行运行
java -jar mydubbo-server.jar
就可以运行dubbo服务了。(注:lib目录下的所有jar包是mydubbo-server.jar的依赖jar)
执行jar文件
E:\dubbo\incubator-dubbo\dubbo-demo\dubbo-demo-provider\target> java -jar .\mydubbo-server.jar
出现异常
[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文件的异常。
解决方案
现在的解决方案是将所有的spring.schemas合并在一起,而不用去加载单个jar里面的映射文件。所以我们使用maven的shade插件将所有jar里的spring.schemas文件进行合并,在最终生成的单一jar包里,spring.schemas包含了所有出现过的映射
- 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\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!