技術點: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包
<plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> <archive> <manifest> <mainClass>com.main.VcenterCollectMain</mainClass> </manifest> </archive> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> </plugin>
利用命令: 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上有一篇帖子:
http://chenzhou123520.iteye.com/blog/1971322 說明了原因,並給出瞭解決方案
好吧,按照帖子方案選擇了maven-shade-plugin 插件,修改配置如下:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version> 1.7.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>com.chenzhou.test.Main</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin>
主要是靠下面配置(打包時分別合併所有的spring.schemas與spring.handlers文件,這樣就不會丟失):
<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.ManifestResourceTransformer"> <mainClass>com.main.VcenterCollectMain</mainClass> </transformer> </transformers>
這段配置意思是把spring.handlers和spring.schemas文件以append方式加入到構建的jar包中。
好了,接着打包:mvn clean package ,這下前面的命名空間問題解決了,但虎去狼來啊,又有新問題:由於項目採用mybatis,而且採用接口形式開發,將mapper文件統統放到了java類目錄,而不是資源目錄,截圖如下:
結果,導致maven打包時,這些xml文件打不進去,沒辦法,接着引入<resource>配置:
<resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource>
好了,這下mapper打進去了,運行時又出錯了,找不到類,這些類正好是通過system方式管理的本地jar:
<dependency> <groupId>vijava</groupId> <artifactId>vijava</artifactId> <version>1.0</version> <scope>system</scope> <systemPath>${project.basedir}/lib/vijava55b20130927.jar</systemPath> </dependency>
又開始百度,,找到答案,說是要利用<resource>配置指定jar位置,加入如下配置:
<resource> <targetPath>lib/</targetPath> <directory>lib/</directory> <includes> <include>**/vijava55b20130927.jar</include> </includes> </resource>
好了,打包mvn clean package ,打包正常,這個jar在jar包中在單獨的lib目錄中,好了準備運行jar試試,結果,報錯,說找不到類,而該類就是lib中的類,看來這樣雖然可以將system管理的包打到jar中,但運行時卻引用不到,看來不行啊,繼續找,找。。
有人說,將jar安裝到本地倉庫,我也想啊,但是,別人拿到項目還不是得在自己的本地再次安裝一遍,太費事,採取終極方案:
添加 in project repository,在新機器上執行時就不用運行mvn install:install-file命令了
配置如下:
<repositories> <repository> <id>in-project</id> <name>In Project Repo</name> <url>file://${project.basedir}/lib</url> </repository> </repositories> <dependency> <groupId>vijava</groupId> <artifactId>vijava</artifactId> <version>1.0</version> </dependency>
本項目配置如下:
注意:
你的jar包及路徑必須嚴格遵循格式: /groupId/artifactId/version/artifactId-verion.jar 本例中: lib/org/richard/my-jar/1.0/my-jar-1.0.ja maven-shade-plugin插件有個配置屬性:createDependencyReducedPom,默認值爲true. 注意這個屬性,如果你用這個插件來deploy,或者發佈到中央倉庫 這個屬性會縮減你的pom文件,會把你依賴的<dependency>幹掉 正確的做法是把這個值改成false,如果爲true,則會生成一個裁剪的pom文件: dependency-reduced-pom.xml 應該將該值改爲false: <configuration> <createDependencyReducedPom>false</createDependencyReducedPom> </configuration>
最後給出本項目完整配置的pom:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.huhu</groupId> <artifactId>VcenterCollector</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>VcenterCollector</name> <url>http://maven.apache.org</url> <repositories> <repository> <id>in-project</id> <name>In Project Repo</name> <url>file://${project.basedir}/lib</url> </repository> </repositories> <properties> <spring.version>4.1.4.RELEASE</spring.version> <mybatis.version>3.2.6</mybatis.version> <slf4j.version>1.7.7</slf4j.version> <log4j.version>1.2.17</log4j.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.8</version> <scope>test</scope> </dependency> <!-- spring --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.5</version> </dependency> <!-- end spring --> <!-- mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>${mybatis.version}</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.30</version> </dependency> <!-- 添加druid連接池包 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.12</version> </dependency> <dependency> <groupId>dom4j</groupId> <artifactId>dom4j</artifactId> <version>1.6.1</version> </dependency> <dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</artifactId> <version>2.4</version> <classifier>jdk15</classifier> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>vijava</groupId> <artifactId>vijava</artifactId> <version>1.0</version> </dependency> </dependencies> <build> <finalName>VcenterCollector</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version> 1.7.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <createDependencyReducedPom>false</createDependencyReducedPom> <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.ManifestResourceTransformer"> <mainClass>com.main.VcenterCollectMain</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> </resources> </build> </project>