有时候,因为项目的须要,咱们会将源码编译后以工具包(class打成jar包)的形式对外提供,此时,
你的 jar 包不必定要是可执行的,只要能经过编译,能被别人以 import 的方式调用就好了。但还有的
状况是,咱们的 jar 包是要可执行的,即能直接在 cmd 下直接运行。前者的打包很简单,在 eclipse 中,
直接选中要打包的 java 文件和其它资源、依赖文件, export → Java → JAR file 便可。须要注意的是,
这种方式导出的 jar 包是不可执行的,好比你执行以下的语句:
java -jar test.jar
java -classpath test.jar com.test_maven.App
会直接报错:没法找到主类或者找不到 xxx 依赖包/类,这是因为你没有定义 MANIFEST.MF 资源描述文件所致,
或者你直接把依赖的 jar 包打进了你最终的 jar,而这种嵌套的依赖 jar 包是不能直接被程序 import 识别的。
下面咱们看看如何在 eclipse 中构建一个可执行的 jar 包。html
(1)最简单的仍是依赖于 eclipse 的导出功能:java
export → java → Runnable JAR file,这种形式的导出程序员
能够经过 lanuch configuration 指定一个 MainClass,并会自动生成 MANIFEST.MF ,并且会帮你把依赖的 jar 包解压出来,一并打进最终的 jar 包,这样就能被你的代码 import 引用了。apache
(2)上述方法是 eclipse 自带的,eclipse 也有个专门的插件叫作 Fat Jar,支持许多定制化的功能,json
具体请参见下面的连接。可是这个插件有些缺陷,好比修改源码后若是你不 clean & rebuild project,缓存
它会使用缓存从新打包,这样你的编译代码仍是老的,会形成执行错误,并且这样是十分不方便的。oracle
用Fat Jar Eclipse Plug-In打包可执行jar文件eclipse
http://8366.iteye.com/blog/480652maven
(3)稍微大点的项目都会用 maven 或者 ant 来构建,在 maven 工程中,咱们也能够很方便的打包成可执行的 jar
包。默认Maven生成的JAR包只包含了编译生成的.class文件和项目资源文件,而要获得一个能够直接在命令行经过
java命令运行的JAR文件,还要知足两个条件:工具
Maven有好几个插件能帮助用户完成上述任务,不过用起来最方便的仍是maven-shade-plugin,它可让用户配置
Main-Class的值,而后在打包的时候将值填入/META-INF/MANIFEST.MF文件。关于项目的依赖,它很聪明地将依赖
JAR文件所有解压后,再将获得的.class文件连同当前项目的.class文件一块儿合并到最终的CLI包中,这样,在执行CLI JAR文件的时候,全部须要的类就都在Classpath中了。下面是一个配置样例:
<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.ManifestResourceTransformer"> <mainClass>com.juvenxu.mavenbook.HelloWorldCli</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin>
上述例子中的,个人Main-Class是com.juvenxu.mavenbook.HelloWorldCli,构建完成后,对应于一个常规的
hello-world-1.0.jar文件,我还获得了一个hello-world-1.0-cli.jar文件。细心的读者可能已经注意到了,这里用的
是cli这个classifier。最后,我能够经过java -jar hello-world-1.0-cli.jar命令运行程序。固然了,若是你须要更加自由
的打包方式,那就用 maven-assembly-plugin 吧。它支持各类打包文件格式,包括zip、tar.gz、tar.bz2等等,经过一个打包
描述文件(例如 src/main/assembly.xml),它可以帮助用户选择具体打包哪些文件集合、依赖、模块、和甚至本地仓库文件,
每一个项的具体打包路径用户也能自由控制。好比下面的配置经过设置 assembly 文件的配置节点 dependencySets/includes,来实现 maven build 生成的 jar 包只包含指定的 jar 依赖。
<assembly ... ooxx> <fileSets> </fileSets> <dependencySets> <dependencySet> <unpack>false</unpack> <outputDirectory>lib</outputDirectory> <scope>runtime</scope> <includes> <include>groupId:artifactId</include> </includes> </dependencySet> </dependencySets> </assembly>
具体请参见:
Maven实战(九)——打包的技巧
http://www.infoq.com/cn/news/2011/06/xxb-maven-9-package
maven发布 jar类型的工程
http://mengyunshuitian.iteye.com/blog/1759864
maven assembly plugin dependencySet with transitive dependencies
http://maven.apache.org/plugins/maven-assembly-plugin/assembly.html#dependencySet
(4)可使用两个 Maven 插件帮助您完成:maven-jar-plugin 和 maven-dependency-plugin。
maven-jar-plugin 能够作不少事情,但在这里,咱们只对使用它来修改默认 MANIFEST.MF 文件的内容感兴趣。
在您的 POM 文件的插件部分添加清单 1 所示代码:
清单 1. 使用 maven-jar-plugin 修改 MANIFEST.MF
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> <classpathPrefix>lib/</classpathPrefix> <mainClass>com.mypackage.MyClass</mainClass> </manifest> </archive> </configuration> </plugin>
全部 Maven 插件经过一个 <configuration> 元素公布了其配置,在本例中,maven-jar-plugin 修改它的 archive 属性,
特别是存档文件的 manifest 属性,它控制 MANIFEST.MF 文件的内容。包括 3 个元素:
addClassPath:将该元素设置为 true 告知 maven-jar-plugin 添加一个 Class-Path 元素到 MANIFEST.MF 文件,以及在
Class-Path 元素中包括全部依赖项。
classpathPrefix:若是您计划在同一目录下包含有您的全部依赖项,做为您将构建的 JAR,那么您能够忽略它;不然使用
classpathPrefix 来指定全部依赖 JAR 文件的前缀。在清单 1 中,classpathPrefix 指出,相对存档文件,全部的依赖项
应该位于 “lib” 文件夹。
mainClass:当用户使用 lib 命令执行 JAR 文件时,使用该元素定义将要执行的类名。
当您使用这 3 个元素配置好了 MANIFEST.MF 文件以后,下一步是将全部的依赖项复制到 lib 文件夹。为此,使用
maven-dependency-plugin,如清单 2 所示:
清单 2. 使用 maven-dependency-plugin 将依赖项复制到库
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>copy</id> <phase>install</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory> ${project.build.directory}/lib </outputDirectory> </configuration> </execution> </executions> </plugin>
maven-dependency-plugin 有一个 copy-dependencies,目标是将您的依赖项复制到您所选择的目录。本例中,我将依赖项复制到
build 目录下的 lib 目录(project-home/target/lib)。
将您的依赖项和修改的 MANIFEST.MF 放在适当的位置后,您就能够用一个简单的命令启动应用程序:
java -jar jarfilename.jar
更多技巧,您能够参考:
关于 Apache Maven 您不知道的 5 件事
http://www.ibm.com/developerworks/cn/java/j-5things13/
(5)固然了,若是你不怕麻烦的话,手动打包,本身创建、维护 MANIFEST.MF 文件也是能够的,你能够参考以下连接:
http://blog.csdn.net/mango_song/article/details/8531389
http://gushuizerotoone.iteye.com/blog/1757002
(6)把包发布到 nexus
项目上右键 → run as → maven build
附:Maven的坐标GAV(groupId, artifactId, version)定义
pom定义了最小的maven元素,容许groupId,artifactId,version。在 POM 中,groupId, artifactId, packaging, version 叫做 maven 坐标,它能惟一的肯定一个项目。有了 maven 坐标,咱们就能够用它来指定咱们的项目所依赖的其余项目,插件,或者父项目。通常 maven 坐标写成以下的格式:
groupId:artifactId:packaging:version
<dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</artifactId> <version>2.2.2</version> <classifier>jdk15</classifier> </dependency>
这样配置便可找到json-lib-2.2.2-jdk15.jar ,其余的就不解释了,应该明白他的用途了吧。
POM关系:
主要为依赖,继承,合成
REF:
使用maven插件对java工程进行打包
http://chenzhou123520.iteye.com/blog/1706242
关于如何从jar包中读取配置、属性文件,请参考:
http://my.oschina.net/leejun2005/blog/95186
Apache Maven 入门篇(下)
http://www.oracle.com/technetwork/cn/community/java/apache-maven-getting-started-2-405568-zhs.html
maven 配置篇 之pom.xml(一)
http://zyl.iteye.com/blog/41754
Maven最佳实践:划分模块
http://juvenshun.iteye.com/blog/305865
在Eclipse中建立Maven多模块工程的例子
http://www.blogways.net/blog/2013/05/13/maven-multi-modules-demo.html
每一个程序员都该学会的Maven知识
https://mp.weixin.qq.com/s/UnMyH65RtWPHdRHMfIsxlg
Maven 虐我千百遍,我待 Maven 如初恋