现状

该项目使用了Maven,并且引入了Spring,包含代码、配置文件、Jar包,使用的是IDEA来作为开发工具,项目的产出物是要打包成一个可运行的Jar包。通过IDEA的打包工具也可以打包成功,只不过需要自己向MANIFEST.MF里面写入Class-Path(引入的Jar包多的时候就比较烦了,或许有简单的方法是我不知道的吧)。鉴于项目使用了Maven,且Maven里面拥有众多优秀的插件,最终决定使用Maven来作为项目的打包工具。

目标

  • 自己的代码编译后作为一个主要的启动Jar
  • 自己的源代码也打包成为一个Jar
  • 引用的Jar包放入到lib目录下
  • 需要的配置文件放在conf目录下
  • 将我们的启动Jar、lib目录、conf目录打包成一个文件

准备

  • 工具

    • Maven(必需的)
    • IDEA(非必需,看个人习惯)
  • Maven插件(核心的)
    • maven-compiler-plugin
    • maven-jar-plugin
    • maven-dependency-plugin
    • maven-resources-plugin
    • maven-source-plugin
    • maven-assembly-plugin

POM详解

基本属性

  1. <project>
  2. [...]
  3. <properties>
  4. <!--项目使用的JDK版本-->
  5. <jdk.version>1.8</jdk.version>
  6. <!--项目使用的Spring版本-->
  7. <spring.version>4.3.10.RELEASE</spring.version>
  8. <!--项目文件编码-->
  9. <sourceEncoding>UTF-8</sourceEncoding>
  10. </properties>
  11. [...]
  12. <dependencies>
  13. <!--项目的依赖包-->
  14. [...]
  15. </dependencies>
  16. </project>

插件配置

  1. <project>
  2. [...]
  3. <build>
  4. <plugins>
  5. <!--我们要使用的插件就在这里-->
  6. [...]
  7. </plugins>
  8. </build>
  9. [...]
  10. </project>

maven-compiler-plugin

这个插件是maven在编译项目的时候需要的信息,主要是为其指明JDK版本信息以及编码方式。一般的maven项目初始化后的默认JDK版本是1.5的,如果不注意就会出现莫名其妙的错误。

  1. <plugin>
  2. <groupId>org.apache.maven.plugins</groupId>
  3. <artifactId>maven-compiler-plugin</artifactId>
  4. <version>3.6.2</version>
  5. <configuration>
  6. <source>${jdk.version}</source>
  7. <target>${jdk.version}</target>
  8. <encoding>${project.build.sourceEncoding}</encoding>
  9. </configuration>
  10. </plugin>

maven-jar-plugin

这个插件就是用在打包时,指明必要的信息的,它还有一些其他的定制化的设置可以参考 官方文档

  1. <plugin>
  2. <groupId>org.apache.maven.plugins</groupId>
  3. <artifactId>maven-jar-plugin</artifactId>
  4. <configuration>
  5. <archive>
  6. <!-- 清单文件 -->
  7. <manifest>
  8. <!-- 指明我们的项目启动入口,即包含main方法的那个类 -->
  9. <mainClass>cn.xxx.Abcd</mainClass>
  10. <!-- 需要增加类的加载路径 -->
  11. <addClasspath>true</addClasspath>
  12. <!--
  13. 类的加载路径,这里的路径是以打包后的jar文件为基准的
  14. 也就是说这个lib就在打包后的jar所在的那个文件夹下
  15. -->
  16. <classpathPrefix>lib/</classpathPrefix>
  17. </manifest>
  18. <manifestEntries>
  19. <!--
  20. 这里的conf会添加到maven打包时产生的MANIFEST.MF的Class-Path节点中
  21. 通常的,我们在Spring中的配置文件都是通过classpath来指明位置的,所以这里的说明可以让我们把配置文件拿出来单独放在一起
  22. -->
  23. <Class-Path>conf/</Class-Path>
  24. </manifestEntries>
  25. </archive>
  26. </configuration>
  27. </plugin>

maven-dependency-plugin

这个插件的作用就是把一些依赖包拷贝或者解压到指定的位置去。我们这里仅用了其copy的目标,它的其他目标请参考 官方文档

  1. <!-- 拷贝依赖的jar包到lib目录 -->
  2. <plugin>
  3. <groupId>org.apache.maven.plugins</groupId>
  4. <artifactId>maven-dependency-plugin</artifactId>
  5. <executions>
  6. <execution>
  7. <id>copy</id>
  8. <!--绑定到maven的生命周期的package阶段-->
  9. <phase>package</phase>
  10. <goals>
  11. <!--指明我们的目标:拷贝依赖-->
  12. <goal>copy-dependencies</goal>
  13. </goals>
  14. <configuration>
  15. <!--
  16. 指明我们拷贝的依赖要放到哪个文件夹下面
  17. 这里指的是项目的: /项目根目录/target/lib 目录下
  18. -->
  19. <outputDirectory>
  20. ${project.build.directory}/lib
  21. </outputDirectory>
  22. </configuration>
  23. </execution>
  24. </executions>
  25. </plugin>

maven-resources-plugin

这个主要用来指明资源文件的编码方式了,但是这么插件还有许多其他的功能,具体详情请参考 官方文档

  1. <plugin>
  2. <groupId>org.apache.maven.plugins</groupId>
  3. <artifactId>maven-resources-plugin</artifactId>
  4. <version>2.5</version>
  5. <configuration>
  6. <encoding>${project.build.sourceEncoding}</encoding>
  7. </configuration>
  8. </plugin>

maven-source-plugin

这个插件用来把我们的源代码也打包成一个Jar文件,这里我们使用其一部分属性,其余属性的使用请参考 官方文档

  1. <plugin>
  2. <artifactId>maven-source-plugin</artifactId>
  3. <version>2.1</version>
  4. <configuration>
  5. <!--这里你可以添加一个outputDirectory节点来指明这个文件的输出目录,fileName来指明其输出的名字-->
  6. <attach>true</attach>
  7. </configuration>
  8. <executions>
  9. <execution>
  10. <phase>compile</phase>
  11. <goals>
  12. <goal>jar</goal>
  13. </goals>
  14. </execution>
  15. </executions>
  16. </plugin>

maven-assembly-plugin

好了,怎么打包,前面都做完了,那么这个插件就是来给他们分分类,然后做成一个jar、zip或者tar.gz等等,把我们需要整合到一起的东西给打包到一起。当然,你还可以通过看 官方文档 来进一步了解它。

其实到这一步之前,我们的jar包已经打包完成了,我们的依赖包也都已经拷贝到target/lib下了,同样的,我们的配置文件也已经放到了target/conf下面了,而且我们也已经可以通过java -jar Abcd.jar来运行了。所以,这个插件就是用来把这些东西都放在一起,来做最后一步——整合。

  1. <plugin>
  2. <artifactId>maven-assembly-plugin</artifactId>
  3. <version>3.1.0</version>
  4. <configuration>
  5. <appendAssemblyId>false</appendAssemblyId>
  6. <descriptors>
  7. <!--这个插件需要一个说明器,这里我将它放在src下的assembly目录下-->
  8. <descriptor>src/assembly/assembly.xml</descriptor>
  9. </descriptors>
  10. </configuration>
  11. <executions>
  12. <execution>
  13. <!--这个插件需要绑定到package阶段执行-->
  14. <phase>package</phase>
  15. <goals>
  16. <!--这里是指只执行一次-->
  17. <goal>single</goal>
  18. </goals>
  19. </execution>
  20. </executions>
  21. </plugin>

然后我们在assembly.xml如下所示

  1. <assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
  4. <id>distribution</id>
  5. <formats>
  6. <!--最后要输出的文件格式
  7. 有:zip、tar、tar.gz (or tgz)、tar.bz2 (or tbz2)、tar.snappy、tar.xz (or txz)、jar、dir、war可以选择
  8. -->
  9. <format>zip</format>
  10. <format>tar.gz</format>
  11. </formats>
  12. <!--下面就可以看作是分类的过程了-->
  13. <fileSets>
  14. <fileSet>
  15. <!--这里指明我们的源文件所在处-->
  16. <directory>${basedir}</directory>
  17. <!--这里指明我们的输出目录-->
  18. <outputDirectory>\</outputDirectory>
  19. <!--这里来说明哪些需要包含进来,当然也可以用excludes来说明不包含哪些文件-->
  20. <includes>
  21. <include>README*</include>
  22. <include>LICENSE*</include>
  23. <include>NOTICE*</include>
  24. </includes>
  25. </fileSet>
  26. <fileSet>
  27. <directory>${project.basedir}\src\script</directory>
  28. <outputDirectory>\</outputDirectory>
  29. <includes>
  30. <include>startup.*</include>
  31. <include>shutdown.*</include>
  32. </includes>
  33. </fileSet>
  34. <fileSet>
  35. <directory>${project.build.directory}\lib</directory>
  36. <outputDirectory>\lib</outputDirectory>
  37. <includes>
  38. <include>*.jar</include>
  39. </includes>
  40. </fileSet>
  41. <fileSet>
  42. <directory>${project.build.directory}</directory>
  43. <outputDirectory>\</outputDirectory>
  44. <includes>
  45. <include>${project.build.finalName}.jar</include>
  46. </includes>
  47. </fileSet>
  48. <fileSet>
  49. <directory>${project.build.directory}\conf</directory>
  50. <outputDirectory>\conf</outputDirectory>
  51. <includes>
  52. <include>*.properties</include>
  53. </includes>
  54. </fileSet>
  55. </fileSets>
  56. <dependencySets>
  57. <dependencySet>
  58. <!--这里用来指明当打包时我们的依赖文件(*.jar)不要解压,要原封不动的打包进去-->
  59. <unpack>false</unpack>
  60. <outputDirectory>\lib</outputDirectory>
  61. <useProjectArtifact>false</useProjectArtifact>
  62. <!-- 将scope为runtime的依赖包打包到lib目录下。 -->
  63. <scope>runtime</scope>
  64. </dependencySet>
  65. </dependencySets>
  66. </assembly>

资源说明

我们还需要说明哪些是我们的资源文件,然后这些会打包进我们的Jar文件里去,而打包进去的资源文件自然地可以以类路径访问了。

  1. <resources>
  2. <!-- 控制资源文件的拷贝 -->
  3. <resource>
  4. <!--这里来指明那个文件夹是我们的资源文件夹-->
  5. <directory>src/main/resources</directory>
  6. <includes>
  7. <!--来指明需要包含的文件,这里用通配符来表示了,即指在resources下的任意子目录(包括其本身)下的xml和tld文件-->
  8. <include>**/*.xml</include>
  9. <include>**/*.tld</include>
  10. </includes>
  11. <!--指明这里不需要过滤,注意过滤的文件是不会被打包进去的,就像下面的*.properties文件都不会被打包-->
  12. <filtering>false</filtering>
  13. </resource>
  14. <resource>
  15. <directory>src/main/resources</directory>
  16. <includes>
  17. <include>**/*.properties</include>
  18. </includes>
  19. <filtering>true</filtering>
  20. <!--上面的filter指明这类文件需要过滤出来,那么接下来这个节点说明这类文件还需要输出到/conf目录下-->
  21. <targetPath>${project.build.directory}/conf</targetPath>
  22. </resource>
  23. </resources>

最后

经过以上的步骤之后,我们的项目就算打包完毕了,整个项目目录就是下面这个样子的

  1. \root
  2. |``\lib
  3. | ``\*.jar
  4. |``\conf
  5. | ``\*.properties
  6. |``\Abcd.jar

还有一个跨平台的脚本插件appassembler-maven-plugin,可是我觉得shell这种东西,自己写一写会更好,所以这里仅提供其名字,不提供其用法了。

Maven打包Jar的更多相关文章

  1. MAVEN 打包JAR

    <build> <finalName>edu-service-user</finalName> <resources> <resource> ...

  2. Maven打包jar项目

    默认情况下,使用maven打包的jar项目(执行maven install)不会包含其他包引用,要想打包为带其他项目引用的jar,需要加入插件 要得到一个可以直接在命令行通过java命令运行的JAR文 ...

  3. maven 打包jar && lib

    一.springboot 打包成jar 1.pom.xml <build> <!-- jar的名称--> <finalName>shiro</finalNam ...

  4. 部署项目问题(maven打包jar不对应,导致启动时一直找不到某个类)

    项目是springboot+maven  打包用maven的插件package 下面是打包后的目录结构  project-1.0 和project-1.0.tar.gz是一样的  区别就是一个是压缩包 ...

  5. idea使用maven打包jar包

    1.在pom.xml中加入以下内容: <?xml version="1.0" encoding="UTF-8"?> <project xmln ...

  6. maven打包 jar

    最后更新时间: 2014年11月23日 1. maven-shade-plugin 2. maven-assembly-plugin 3. maven-onejar-plugin maven-shad ...

  7. maven打包jar源码至私服

    1. setting文件 配置私服中设置的用户和密码 <servers> <server> <id>releases</id> <username ...

  8. maven打包jar包

    参考http://www.cnblogs.com/justinzhang/p/4983633.html 新建jar类型的maven project (选择simple project ) 配置 < ...

  9. java maven打包jar 方法参数名变var1,var2之类的无意义参数名怎么办

    这是idea 对.class反编译的结果.要想看完整源码,可以使用maven-source-plugin,在pom.xml里配置: <plugin> <groupId>org. ...

随机推荐

  1. python爬虫scrapy框架——人工识别知乎登录知乎倒立文字验证码和数字英文验证码

    目前知乎使用了点击图中倒立文字的验证码: 用户需要点击图中倒立的文字才能登录. 这个给爬虫带来了一定难度,但并非无法解决,经过一天的耐心查询,终于可以人工识别验证码并达到登录成功状态,下文将和大家一一 ...

  2. 第3阶段——内核启动分析之创建si工程和分析stext启动内核函数(4)

    目标: (1)创建Source Insight 工程,方便后面分析如何启动内核的 (2)分析uboot传递参数,链接脚本如何进入stext的  (3) 分析stext函数如何启动内核:  (3.1) ...

  3. oracle12c之 单机12.1.0.1打补丁

    1. 下载最新的12.1.0.1的DB PSU 与 OPatchp23054354_121010_Linux-x86-64.zipp6880880_121010_Linux-x86-64.zip 2. ...

  4. 【2017集美大学1412软工实践_助教博客】团队作业10——项目复审与事后分析(Beta版本)

    写在前面的话 转眼轰轰烈烈本学期的软工实践就结束了,这个过程中想必在熬夜敲代码,激烈讨论中留下诸多回忆的同时,也收获了不少.恭喜所有团队完成了本阶段冲刺,此外,由于大家的贡献分给的都很平均,将个人贡献 ...

  5. 201521123066《Java程序设计》第七周学习总结

    第7周-集合 本周学习总结 其他注意点: (1)List主要特征: 其元素以线性方式存储 集合中允许存放重复对象 (2)Set中的对象: 不按特定方式排序 没有重复对象 Set最多有一个null元素 ...

  6. 第6周-接口、内部类与Swing

    1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 注1:关键词与内容不求多,但概念之间的联系要清晰,内容覆盖 ...

  7. 201521123028 《Java程序设计》第6周学习总结

    1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 2. 书面作业 Q1.clone方法 1.1 Object ...

  8. 201521123039 《java程序设计》第四周学习总结

    1. 本周学习总结 总结: 1.提到类的继承就会想到继承层次的问题,一般我们都将子类和父类共同的特征放到父类中,将具有特殊用途的方法放在子类中,这样可以有效避免代码冗余. 2.覆盖与重载是不同的概念, ...

  9. iScroll在谷歌浏览器中的问题

    通常情况下,我们会使用iScroll.js做移动端的下拉刷新和上拉加载功能,当然,还有很多其他功能. 不过,在使用iScroll的时候,在谷歌浏览器中出现不支持的情况,即,做移动的时候,出现卡顿或是每 ...

  10. webservice07#契约优先#webservice实现简单的动态web项目

    1, 用户管理 User{username,password,nickname} 属性. 2,契约优先[ 先用schema做标准来写wsdl.再生成服务器端的接口,再编写接口的类] 在src下创建目录 ...