技术点:spring加载xsd过程:

http://blog.csdn.net/bluishglc/article/details/7596118

案发背景:

1、一个使用maven管理的普通项目(vcenter-collector :关于Vcenter数据采集)

2、项目主要技术: java + mybatis(基于接口形式)+其他

3、项目中有一个非maven仓库的jar包:vijava(做vcenter数据采集的),在项目中以system方式引用

  (该jar放在${project.basedir}/lib下)

需求: 将该项目打包为一个可执行jar

案发经过:

1、引用maven的插件(maven-assembly-plugin)打有依赖的jar包

maven-assembly-plugin
com.main.VcenterCollectMain
jar-with-dependencies

利用命令: mvn clean assembly:assembly 进行打包,

打好包后运行:java -jar Vcenter-Collector.jar

运行报错:

org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/context]

然后开始在网上搜罗答案,结果有惊喜啊,发现spring配置文件在加载的时候需要相关的xsd配合,只管自己没了解spring配置文件加载细节,在iteye上有一篇帖子:

  说明了原因,并给出了解决方案

好吧,按照帖子方案选择了maven-shade-plugin 插件,修改配置如下:

org.apache.maven.plugins
maven-shade-plugin
 1.7.1
package
shade
   
 
com.chenzhou.test.Main

主要是靠下面配置(打包时分别合并所有的spring.schemas与spring.handlers文件,这样就不会丢失):

  
META-INF/spring.handlers
   
META-INF/spring.schemas
com.main.VcenterCollectMain

这段配置意思是把spring.handlers和spring.schemas文件以append方式加入到构建的jar包中。

好了,接着打包:mvn clean package ,这下前面的命名空间问题解决了,但虎去狼来啊,又有新问题:由于项目采用mybatis,而且采用接口形式开发,将mapper文件统统放到了java类目录,而不是资源目录,截图如下:

结果,导致maven打包时,这些xml文件打不进去,没办法,接着引入<resource>配置:

           
                
src/main/java
                
                    
**/*.properties
                    
**/*.xml
                
                
false
            
            
                
src/main/resources
                
                    
**/*.properties
                    
**/*.xml
                
                
false
            

好了,这下mapper打进去了,运行时又出错了,找不到类,这些类正好是通过system方式管理的本地jar:

 
vijava
vijava
1.0
system
${project.basedir}/lib/vijava55b20130927.jar
  

又开始百度,,找到答案,说是要利用<resource>配置指定jar位置,加入如下配置:

   
lib/
   
lib/
   
       
**/vijava55b20130927.jar
   

好了,打包mvn clean package ,打包正常,这个jar在jar包中在单独的lib目录中,好了准备运行jar试试,结果,报错,说找不到类,而该类就是lib中的类,看来这样虽然可以将system管理的包打到jar中,但运行时却引用不到,看来不行啊,继续找,找。。

有人说,将jar安装到本地仓库,我也想啊,但是,别人拿到项目还不是得在自己的本地再次安装一遍,太费事,采取终极方案:

  添加 in project repository,在新机器上执行时就不用运行mvn install:install-file命令了

配置如下:

   
in-project
In Project Repo
file://${project.basedir}/lib
   
    
vijava
     
vijava
      
1.0

本项目配置如下:

 

注意:

你的jar包及路径必须严格遵循格式:/groupId/artifactId/version/artifactId-verion.jar本例中: lib/org/richard/my-jar/1.0/my-jar-1.0.jamaven-shade-plugin插件有个配置属性:createDependencyReducedPom,默认值为true.注意这个属性,如果你用这个插件来deploy,或者发布到中央仓库这个属性会缩减你的pom文件,会把你依赖的
干掉正确的做法是把这个值改成false,如果为true,则会生成一个裁剪的pom文件:     dependency-reduced-pom.xml     应该将该值改为false:
         
false
   

最后给出本项目完整配置的pom:

4.0.0
com.huhu
VcenterCollector
0.0.1-SNAPSHOT
jar
VcenterCollector
http://maven.apache.org
    
in-project
    
In Project Repo
    
file://${project.basedir}/lib
4.1.4.RELEASE
3.2.6
1.7.7
1.2.17
UTF-8
junit
junit
4.8
test
org.springframework
spring-core
${spring.version}
org.springframework
spring-context
${spring.version}
org.springframework
spring-webmvc
${spring.version}
org.springframework
spring-web
${spring.version}
org.springframework
spring-aop
${spring.version}
org.springframework
spring-tx
${spring.version}
org.springframework
spring-jdbc
${spring.version}
org.aspectj
aspectjweaver
1.8.5
org.mybatis
mybatis
${mybatis.version}
org.mybatis
mybatis-spring
1.2.2
mysql
mysql-connector-java
5.1.30
com.alibaba
druid
1.0.12
dom4j
dom4j
1.6.1
net.sf.json-lib
json-lib
2.4
jdk15
commons-io
commons-io
2.4
org.slf4j
slf4j-log4j12
${slf4j.version}
    
vijava
    
vijava
    
1.0
VcenterCollector
org.apache.maven.plugins
maven-compiler-plugin
1.6
1.6
org.apache.maven.plugins
maven-shade-plugin
 1.7.1
package
shade
false
META-INF/spring.handlers
META-INF/spring.schemas
com.main.VcenterCollectMain
                
src/main/java
                
                    
**/*.properties
                    
**/*.xml
                
                
false
            
            
                
src/main/resources
                
                    
**/*.properties
                    
**/*.xml
                
                
false