记一次 Spring Maven 打包的坑

Posted ImportNew

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记一次 Spring Maven 打包的坑相关的知识,希望对你有一定的参考价值。


来源:Hosee,

my.oschina.net/hosee/blog/1507336


背景:


一个将kafka数据入库的项目,由于偷懒,直接想改动现成的Spring-ibait项目。


做完dao层后,要将项目打成一个jar包,然后部署到服务器上运行。


项目使用Maven来管理依赖。


问题:


在网上查了相关Maven配置如下:


<build>  

    <plugins>  

   

        <plugin>  

            <groupId>org.apache.maven.plugins</groupId>  

            <artifactId>maven-assembly-plugin</artifactId>  

            <version>2.5.5</version>  

            <configuration>  

                <archive>  

                    <manifest>  

                        <mainClass>com.xxg.Main</mainClass>  

                    </manifest>  

                </archive>  

                <descriptorRefs>  

                    <descriptorRef>jar-with-dependencies</descriptorRef>  

                </descriptorRefs>  

            </configuration>  

            <executions>  

                <execution>  

                    <id>make-assembly</id>  

                    <phase>package</phase>  

                    <goals>  

                        <goal>single</goal>  

                    </goals>  

                </execution>  

            </executions>  

        </plugin>  

   

    </plugins>  

</build>


使用mvn package打包,抛出如下错误:


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

Offending resource: class path resource [beans.xml] 

 

at org.springframework.beans.factory.parsing.FailFastProblemReporter.error(FailFastProblemReporter.java:68)

at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:85) 

at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:80) 

at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.error(BeanDefinitionParserDelegate.java:284)

at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1335)

at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1328)

at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:135)

at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:93)

at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:493)

at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:390)

at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:334)

at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302)

at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:143)

at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:178)

at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:149)

at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:212)

at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:126)

at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:92)

at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:130)

at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:467)

at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:397)

at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139) 

at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83) 

at cn.com.ckx.service.UserServiceTest.testAdd(UserServiceTest.java:11) 

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 

at java.lang.reflect.Method.invoke(Method.java:597) 

at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) 

at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 

at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) 

at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) 

at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76) 

at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) 

at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) 

at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) 

at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) 

at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) 

at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) 

at org.junit.runners.ParentRunner.run(ParentRunner.java:236) 

at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49) 

at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 

at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 

at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 

at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 

at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)


查了网上的资料,发现是对应jar包没有添加。可是查了半天发现pom中的依赖都是全的。


解决:


如果项目中用到了Spring Framework,将依赖打到一个jar包中,运行时会出现读取XML schema文件出错。原因是Spring Framework的多个jar包中包含相同的文件spring.handlers和spring.schemas,如果生成一个jar包会互相覆盖。为了避免互相影响,可以使用AppendingTransformer来对文件内容追加合并:


<build>  

    <plugins>  

   

        <plugin>  

            <groupId>org.apache.maven.plugins</groupId>  

            <artifactId>maven-shade-plugin</artifactId>  

            <version>2.4.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.xxg.Main</mainClass>  

                            </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.schemas</resource>  

                            </transformer>  

                        </transformers>  

                    </configuration>  

                </execution>  

            </executions>  

        </plugin>  

   

    </plugins>  

</build>


再次报错:


java.lang.SecurityException: Invalid signature file digest for Manifest main attributes


这是由于一些包重复引用,打包后的 META-INF 目录多出了一些 *.SF 等文件所致。


pom中添加:


<configuration>

          <filters>

            <filter>

              <artifact>*:*</artifact>

              <excludes>

                <exclude>META-INF/*.SF</exclude>

                <exclude>META-INF/*.DSA</exclude>

                <exclude>META-INF/*.RSA</exclude>

              </excludes>

            </filter>

          </filters>

</configuration>


最终的pom:


<build>

        <plugins>

            <plugin>

                <groupId>org.apache.maven.plugins</groupId>

                <artifactId>maven-shade-plugin</artifactId>

                <version>1.4</version>

                <executions>

                    <execution>

                        <phase>package</phase>

                        <goals>

                            <goal>shade</goal>

                        </goals>

                        <configuration>

                            <filters>

                                <filter>

                                    <artifact>*:*</artifact>

                                    <excludes>

                                        <exclude>META-INF/*.SF</exclude>

                                        <exclude>META-INF/*.DSA</exclude>

                                        <exclude>META-INF/*.RSA</exclude>

                                    </excludes>

                                </filter>

                            </filters>

                            <transformers>

                                <transformer

                                    implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">

                                    <mainClass>com.defonds.RsaEncryptor</mainClass>

                                </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.schemas</resource>

                                </transformer>

                            </transformers>

                        </configuration>

                    </execution>

                </executions>

            </plugin>

        </plugins>

    </build>


Reference:


  1. http://blog.csdn.net/xiao__gui/article/details/47341385

  2. http://www.mamicode.com/info-detail-447722.html


关注「ImportNew」,看技术干货

以上是关于记一次 Spring Maven 打包的坑的主要内容,如果未能解决你的问题,请参考以下文章

记一次Spring项目打包问题排查

记一次Spring项目打包问题排查

eclipse 打包maven项目的坑

记一次打包的诡异现象

记一次 webpack 打包体积优化

记一次向maven中央仓库提交依赖包