0
点赞
收藏
分享

微信扫一扫

将Maven工程打包成可执行JAR包的方法

楚木巽 2023-08-10 阅读 38


如果项目中有需要后台执行的任务,但是主要的逻辑都在Java代码中,那么我采用的方式是单独建立一个maven模块打成jar包,然后在linux后台通过命令执行Jar包的Main函数:







Shell




java                   -         classpath          backtask         .jar                   "net.crazyant.RunWebService"




于是就有个前提,得将maven模块打包成jar包,原本很简单的事情,却出现了很多问题。

原始打包方式:使用maven-assembly-plugin

POM配置片段为:







XHTML



<build>

             <plugins>

                 <plugin>

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

                     <artifactId>         maven-jar-plugin         </artifactId>

                 </plugin>            

                 <plugin>

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

                     <version>         2.2.1         </version>

                     <configuration>

                         <finalName>         mdm-v3-backtasks         </finalName>

                         <descriptorRefs>

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

                         </descriptorRefs>

                     </configuration>

                     <executions>

                         <execution>

                             <phase>         package         </phase>

                             <goals>

                                 <goal>         single         </goal>

                             </goals>

                         </execution>

                     </executions>

                 </plugin>

                 <plugin>

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

                     <artifactId>         maven-resources-plugin         </artifactId>

                     <version>         2.6         </version>

                     <configuration>

                         <encoding>         UTF-8         </encoding>

                     </configuration>

                 </plugin>          

             </plugins>

</build>



这种打包方式,可以生成/target/mdm-v3-backtasks-1.0.0.2.jar的Jar包,在有些工程中是没有问题的,但是我的新工程打包后,却在运行时出现了如下问题:


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

Offending          resource         :                   class                   path          resource                   [         applicationContext         -         backtasks         .         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         :         318         )

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

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

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

                 at          org         .         springframework         .         beans         .         factory         .         xml         .         DefaultBeanDefinitionDocumentReader         .         doRegisterBeanDefinitions         (         DefaultBeanDefinitionDocumentReader         .         java         :         139         )

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

                 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         :         174         )

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

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

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

                 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         :         130         )

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

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

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

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



网上搜了很多文章,发现首先大家都支持的,是maven-assembly-plugin插件,替换成maven-shade-plugin插件。

但是替换成maven-shade-plugin之后,仍然遇到了很多问题:

使用maven-shade-plugin逐步解决问题

使用maven-shade-plugin插件,并没有一下子就把问题解决了,也经过了很多步骤:

1、修改spring.xml的schema编写方式

原始的声明是这样的:


<?         xml          version         =         "1.0"                   encoding         =         "UTF-8"         ?>

<         beans          xmlns         =         "http://www.springframework.org/schema/beans"

             xmlns         :         xsi         =         "http://www.w3.org/2001/XMLSchema-instance"                   xmlns         :         context         =         "http://www.springframework.org/schema/context"

             xsi         :         schemaLocation         =         "

            http://www.springframework.org/schema/beans

            http://www.springframework.org/schema/beans/spring-beans.xsd

            http://www.springframework.org/schema/context

            http://www.springframework.org/schema/context/spring-context.xsd"         >




作如下修改,把xsd的版本加上:


<?         xml          version         =         "1.0"                   encoding         =         "UTF-8"         ?>

<         beans          xmlns         =         "http://www.springframework.org/schema/beans"

             xmlns         :         xsi         =         "http://www.w3.org/2001/XMLSchema-instance"                   xmlns         :         context         =         "http://www.springframework.org/schema/context"

             xsi         :         schemaLocation         =         "

            http://www.springframework.org/schema/beans

            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

            http://www.springframework.org/schema/context

            http://www.springframework.org/schema/context/spring-context-3.0.xsd"         >




2、引入maven-shade-plugin插件的打包方式遇到的问题

将原来的maven-assembly-plugin替换成新的打包方式:


<         build         >

          <         finalName         >         mdm         -         v3         -         backtasks         <         /         finalName         >

          <         plugins         >

          <         plugin         >

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

          <         artifactId         >         maven         -         jar         -         plugin         <         /         artifactId         >

          <         /         plugin         >

          <         plugin         >

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

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

          <         version         >         2.4.2         <         /         version         >

          <         executions         >

          <         execution         >

          <         phase         >         package         <         /         phase         >

          <         goals         >

          <         goal         >         shade         <         /         goal         >

          <         /         goals         >

          <         /         execution         >

          <         /         executions         >

          <         /         plugin         >

          <         plugin         >

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

          <         artifactId         >         maven         -         resources         -         plugin         <         /         artifactId         >

          <         version         >         2.6         <         /         version         >

          <         configuration         >

          <         encoding         >         UTF         -         8         <         /         encoding         >

          <         /         configuration         >

          <         /         plugin         >

          <         /         plugins         >

<         /         build         >



然后就报了下面的错:


Exception          in                   thread                   "main"                   java         .         lang         .         SecurityException         :                   Invalid          signature          file          digest          for                   Manifest          main          attributes

                 at          sun         .         security         .         util         .         SignatureFileVerifier         .         processImpl         (         SignatureFileVerifier         .         java         :         286         )

                 at          sun         .         security         .         util         .         SignatureFileVerifier         .         process         (         SignatureFileVerifier         .         java         :         239         )

                 at          java         .         util         .         jar         .         JarVerifier         .         processEntry         (         JarVerifier         .         java         :         317         )

                 at          java         .         util         .         jar         .         JarVerifier         .         update         (         JarVerifier         .         java         :         228         )

                 at          java         .         util         .         jar         .         JarFile         .         initializeVerifier         (         JarFile         .         java         :         348         )

                 at          java         .         util         .         jar         .         JarFile         .         getInputStream         (         JarFile         .         java         :         415         )

                 at          sun         .         misc         .         URLClassPath         $         JarLoader         $         2.getInputStream         (         URLClassPath         .         java         :         775         )

                 at          sun         .         misc         .         Resource         .         cachedInputStream         (         Resource         .         java         :         77         )

                 at          sun         .         misc         .         Resource         .         getByteBuffer         (         Resource         .         java         :         160         )

                 at          java         .         net         .         URLClassLoader         .         defineClass         (         URLClassLoader         .         java         :         436         )

                 at          java         .         net         .         URLClassLoader         .         access         $         100         (         URLClassLoader         .         java         :         71         )

                 at          java         .         net         .         URLClassLoader         $         1.run         (         URLClassLoader         .         java         :         361         )

                 at          java         .         net         .         URLClassLoader         $         1.run         (         URLClassLoader         .         java         :         355         )

                 at          java         .         security         .         AccessController         .         doPrivileged         (         Native                   Method         )

                 at          java         .         net         .         URLClassLoader         .         findClass         (         URLClassLoader         .         java         :         354         )

                 at          java         .         lang         .         ClassLoader         .         loadClass         (         ClassLoader         .         java         :         425         )

                 at          sun         .         misc         .         Launcher         $         AppClassLoader         .         loadClass         (         Launcher         .         java         :         308         )

                 at          java         .         lang         .         ClassLoader         .         loadClass         (         ClassLoader         .         java         :         358         )

                 at          sun         .         launcher         .         LauncherHelper         .         checkAndLoadMain         (         LauncherHelper         .         java         :         482         )



在http://zhentao-li.blogspot.com/2012/06/maven-shade-plugin-invalid-signature.html找到了解决方法:



You          need          to                   add          the          following          to                   pom         .         xml         :

                  

                 <         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         >




于是加入以上的filter,新的POM内容为:







<         build         >

          <         finalName         >         mdm         -         v3         -         backtasks         <         /         finalName         >

          <         plugins         >

          <         plugin         >

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

          <         artifactId         >         maven         -         jar         -         plugin         <         /         artifactId         >

          <         /         plugin         >

          <         plugin         >

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

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

          <         version         >         2.4.2         <         /         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         >

          <         /         configuration         >

          <         /         execution         >

          <         /         executions         >

          <         /         plugin         >

          <         plugin         >

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

          <         artifactId         >         maven         -         resources         -         plugin         <         /         artifactId         >

          <         version         >         2.6         <         /         version         >

          <         configuration         >

          <         encoding         >         UTF         -         8         <         /         encoding         >

          <         /         configuration         >

          <         /         plugin         >

          <         /         plugins         >

<         /         build         >



修改后提交,不幸的是,又爆出了下面的错误:


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

Offending          resource         :                   class                   path          resource                   [         applicationContext         -         backtasks         .         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         :         318         )

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

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

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

                 at          org         .         springframework         .         beans         .         factory         .         xml         .         DefaultBeanDefinitionDocumentReader         .         doRegisterBeanDefinitions         (         DefaultBeanDefinitionDocumentReader         .         java         :         139         )

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

                 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         :         174         )

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

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

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

                 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         :         130         )

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

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

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

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



最后在http://robert-reiz.com/2011/11/14/832/页面找到了答案:

这是因为项目中包含了很多的Spring Jar,不同的Spring Jar会有相同的文件名称,他们相互冲突,为了避免元数据文件的相互覆盖,应该合并他们,如果使用maven shade plugin的话,可以在POM中加上下面的信息来解决:


<         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         >



对该问题,官方的解释位于:http://maven.apache.org/plugins/maven-shade-plugin/examples/resource-transformers.html

在“Merging Content of Specific Files with AppendingTransformer and XmlAppendingTransformer”小节,解释为:





很多的JAR包含了相同的文件名称,为了避免相互覆盖,可以将他们合并到单个文件中。一个很好的例子,就是spring-context包和plexus-spring包,他俩都有META-INF/spring.handlers文件,这个文件被Spring用来处理XML Schema namespaces,通过如下所示的merge方法,可以解决这个问题



JAR包含了相同的文件名称,为了避免相互覆盖,可以将他们合并到单个文件中。一个很好的例子,就是         spring         -         context包和         plexus         -         spring包,他俩都有         META         -         INF         /         spring         .         handlers文件,这个文件被         Spring用来处理         XML          Schema          namespaces,通过如下所示的         merge方法,可以解决这个问题



问题终于找到了,原来在这里,看下官方贴出来的POM:



<         project         >

           .         .         .

           <         build         >

             <         plugins         >

               <         plugin         >

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

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

                 <         version         >         2.4.2         <         /         version         >

                 <         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         >

                       <         /         transformers         >

                     <         /         configuration         >

                   <         /         execution         >

                 <         /         executions         >

               <         /         plugin         >

             <         /         plugins         >

           <         /         build         >

           .         .         .

<         /         project         >




最终的解决方案

最终的POM文件如下所示:


< build >
< finalName > mdm - v3 - backtasks < / finalName >
< plugins >
< plugin >
< groupId > org . apache . maven . plugins < / groupId >
< artifactId > maven - jar - plugin < / artifactId >
< / plugin >
< plugin >
< groupId > org . apache . maven . plugins < / groupId >
< artifactId > maven - shade - plugin < / artifactId >
< version > 2.4.2 < / version >
< 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 >
< / transformers >
< filters >
< filter >
< artifact > * : * < / artifact >
< excludes >
< exclude > META - INF / * . SF < / exclude >
< exclude > META - INF / * . DSA < / exclude >
< exclude > META - INF / * . RSA < / exclude >
< / excludes >
< / filter >
< / filters >
< / configuration >
< / execution >
< / executions >
< / plugin >
< plugin >
< groupId > org . apache . maven . plugins < / groupId >
< artifactId > maven - resources - plugin < / artifactId >
< version > 2.6 < / version >
< configuration >
< encoding > UTF - 8 < / encoding >
< / configuration >
< / plugin >
< / plugins >
< / build >


使用本POM配置,打包、运行均成功没有出错。

参考链接:

官方:http://maven.apache.org/plugins/maven-shade-plugin/examples/resource-transformers.html

安全问题:http://zhentao-li.blogspot.com/2012/06/maven-shade-plugin-invalid-signature.html

Context问题:http://robert-reiz.com/2011/11/14/832/

 


 

举报

相关推荐

0 条评论