您的位置:首页 > 其它

IDEA打包jar包的多种方式

2017-12-13 22:20 597 查看
本篇文章总结出用IDEA打包jar包的多种方式。项目打包Jar包可以参考如下形式:用IDEA自带的打包形式;用Maven插件maven-shade-plugin打包;用Maven插件maven-assembly-plugin打包。下面跟着小编一起来看下吧

这里总结出用IDEA打包jar包的多种方式,以后的项目打包Jar包可以参考如下形式:
用IDEA自带的打包形式
用Maven插件maven-shade-plugin打包
用Maven插件maven-assembly-plugin打包

用IDEA自带的打包方式:

打开IDEA的file -> Project Structure,进入项目配置页面。如下图:



点击Artifacts,进入Artifacts配置页面,点击 + ,选择如下图的选项。





进入Create JAR from Modules页面,按照如下图配置。




第一步选择Main函数执行的类。
第二步选择如图的选项,目的是对第三方Jar包打包时做额外的配置,如果不做额外的配置可不选这个选项(但不保证打包成功)
第三步需要在src/main目录下,新建一个resources目录,将MANIFEST.MF文件保存在这里面,因为如果用默认缺省值的话,在IDEA12版本下会有bug。

点击OK之后,出现如下图界面,右键点击<output root>,点击Create Directory,创建一个libs,将所有的第三方JAR放进libs目录下。





成功之后,如下图所示:





放入之后,点击我们要打成的jar的名字,这里面是kafka-cps.jar,选择classpath进行配置。





编辑的结果如下:





这里将所有的jar都写在libs/里面。点击OK,回到配置页面。

同时还注意在配置页面,勾选build on make



最后点击配置页面的OK,完成配置。回到IDEA,点击Build->Build Artifacts,选择build



就会生成我们需要的jar包。其位置在项目目录的out目录下/out/artifacts/kafka_cps_jar

下面放一个正确配置的清单文件内容





用maven-shade-plugin打包

上面的打包过程实在是过于的繁琐,而且也没有利用到maven管理项目的特色。为此,我们这里利用maven中的maven-shade-plugin插件。在pom.xml中,我们加入如下的信息来加入插件。

?
这里面配置了一个`configuration`标签内容,在此标签下面 有一个transformer标签,用来配置Main函数的入口(<mainClass>Main.Main</mainClass>),当然此标签内容很复杂,不是上面写的那么简单,上面之所以如此简单,是因为在所有类中(包括第三方Jar)只有一个Main方法。如果第三方jar中有Main方法,就要进行额外的配置,上面这么配置,不一定能执行成功。

在加入这段代码到pom.xml之后,我们就可以用maven的命令去打包了。其指令如下:

?
然后通过java -jar cps-1.0-SNAPSHOT.jar运行。

如果使用IDEA的话,可以通过自带的maven管理工具代替执行上面的命令。如下图所示,依次点击蓝色的部分。





用maven-assembly-plugin打包

上面的方法,我们还需要点击很多命令去打包。这次利用一个新的插件,可以打包更简单。同样,在pom.xml中加入如下代码。上文的maven-shade-plugin插件代码可以删除。最好不要写2个插件代码。

?
这里同样配置了一个manifest标签来配置Main函数的入口。然后通过如下指令来实现打包。

mvn assembly:assembly


如果使用IDEA的话,可以通过自带的maven管理工具代替执行上面的命令。如下图所示,点击蓝色的部分。



然后通过执行java -jar cps-1.0-SNAPSHOT-jar-with-dependencies.jar运行。

现在基本上都是采用maven来进行开发管理,我有一个需求是需要把通过maven管理的java工程打成可执行的jar包,这样也就是说必需把工程依赖的jar包也一起打包。而使用maven默认的package命令构建的jar包中只包括了工程自身的class文件,并没有包括依赖的jar包。我们可以通过配置插件来对工程进行打包,pom具体配置如下:

maven-assembly-plugin

Xml代码  


<plugin>  

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

    <configuration>  

        <appendAssemblyId>false</appendAssemblyId>  

        <descriptorRefs>  

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

        </descriptorRefs>  

        <archive>  

            <manifest>  

                <mainClass>com.chenzhou.examples.Main</mainClass>  

            </manifest>  

        </archive>  

    </configuration>  

    <executions>  

        <execution>  

            <id>make-assembly</id>  

            <phase>package</phase>  

            <goals>  

                <goal>assembly</goal>  

            </goals>  

        </execution>  

    </executions>  

</plugin>  

 

其中<mainClass></mainClass>的值表示此工程的入口类,也就是包含main方法的类,在我的例子中就是com.chenzhou.examples.Main。配置完pom后可以通过执行mvn assembly:assembly命令来启动插件进行构建。构建成功后会生成jar包,这样我们就可以在命令行中通过java -jar XXX.jar来运行jar件了。 

 

不过使用此插件会有一些问题:我在工程中依赖了spring框架的jar包,我打包成功后使用命令来调用jar包时报错如下(内网环境):

 

Shell代码  


org.xml.sax.SAXParseException: schema_reference.4: Failed to read schema document 'http://www.springframework.org/schema/beans/spring-beans-3.0.xsd', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>.  

关于此问题报错的原因,我在网上找到一篇文章对此有比较详细的解释:http://blog.csdn.net/bluishglc/article/details/7596118 简单来说就是spring在启动时会加载xsd文件,它首先会到本地查找xsd文件(一般都会包含在spring的jar包中),如果找不到则会到xml头部定义的url指定路径下中去寻找xsd,如果找不到则会报错。

附:在spring jar包下的META-INF文件夹中都会包含一个spring.schemas文件,其中就包含了对xsd文件的路径定义,具体如下图所示:



图:spring-aop.jar包下META-INF文件夹下的内容



图:spring.schemas文件内容

由于我的工程是在内网,所以通过url路径去寻找肯定是找不到的,但是比较奇怪的是既然spring的jar包中都会包含,那为什么还是找不到呢?

 
原来这是assembly插件的一个bug,具体情况参见:http://jira.codehaus.org/browse/MASSEMBLY-360

该bug产生的原因如下:工程一般依赖了很多的jar包,而被依赖的jar又会依赖其他的jar包,这样,当工程中依赖到不同的版本的spring时,在使用assembly进行打包时,只能将某一个版本jar包下的spring.schemas文件放入最终打出的jar包里,这就有可能遗漏了一些版本的xsd的本地映射,所以会报错。

所以一般推荐使用另外的一个插件来进行打包,插件名称为:maven-shade-plugin,shade插件打包时在对spring.schemas文件处理上,它能够将所有jar里的spring.schemas文件进行合并,在最终生成的单一jar包里,spring.schemas包含了所有出现过的版本的集合,要使用shade插件,必须在pom进行如下配置:

 

Xml代码  


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

                <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.ManifestResourceTransformer">  

                        <mainClass>com.chenzhou.examples.Main</mainClass>  

                    </transformer>  

                    <transformer  

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

                        <resource>META-INF/spring.schemas</resource>  

                    </transformer>  

                </transformers>  

            </configuration>  

        </execution>  

    </executions>  

</plugin>  

上面配置文件中有一段定义:

 

Xml代码  


<transformer  

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

    <resource>META-INF/spring.schemas</resource>  

</transformer>  

  上面这段配置意思是把spring.handlers和spring.schemas文件以append方式加入到构建的jar包中,这样就不会存在出现xsd找不到的情况。

配置完pom后,调用mvn clean install命令进行构建,构建成功后打开工程target目录,发现生成了2个jar包,一个为:original-XXX-0.0.1-SNAPSHOT.jar,另一个为:XXX-0.0.1-SNAPSHOT.jar,其中original...jar里只包含了工程自己的class文件,而另外的一个jar包则包含了工程本身以及所有依赖的jar包的class文件。我们只需要使用第二个jar包就可以了。

参考资料:

http://hi.baidu.com/yuzhi2217/item/2c1714363f25c4f62684f442

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

http://jira.codehaus.org/browse/MASSEMBLY-360
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: