- 浏览: 68987 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
bo_hai:
assembly:single 不包含源代码,只包含依赖的cl ...
关于创建可执行的jar文件 -
lsy:
相当详细的好文!
关于创建可执行的jar文件 -
steven0lisa:
学习了。不过在有动态代码生成的项目中,就要谨慎用了。
Hide Method(隐藏方法) -
steven0lisa:
好久没看源代码了,没记错的话,因为是由以下原因造成的:1.ke ...
编码最佳实践系列之二 -
steven0lisa:
最后一点确实很有艺术,学习了~~~
编码最佳实践系列之一
上周四下午,放翁同学在TOP群中问了这样一个小问题,聊天记录摘录如下:
有同学知道如何用maven来将第三方jar的代码也打入到生成的项目jar中?就好比eclipse可以直接将部分依赖打入到项目jar中
一看到打包,对于jar类型的项目,运行mvn package,就等同于运行mvn jar:jar,那放翁同学的问题,一定是与jar插件有关了,在Maven官方网站,查阅了一下jar插件的相关文档,未果。
临近下班时,我找放翁同学当面了解了一下他真正的需求,就是把该项目的依赖的源码都打入到一个可执行的jar包中,我看了看Maven官方网站的插件列表,以前对assembly插件有点印象,这个插件或许可以胜任放翁的需求,就直接告诉他,试试这个插件吧,第二天早上上班过来,一问放翁,这个东东确实管用,解决了放翁同学的问题。
我以前看过这个插件的文档,但自己却没有使用过,自己也动手Demo一下,和大家分享一下吧
- 创建一个jar项目
tonglin@tonglin-desktop:~$ mvn archetype:generate [INFO] Scanning for projects... [INFO] Searching repository for plugin with prefix: 'archetype'. [INFO] ------------------------------------------------------------------------ [INFO] Building Maven Default Project [INFO] task-segment: [archetype:generate] (aggregator-style) [INFO] ------------------------------------------------------------------------ [INFO] Preparing archetype:generate [INFO] No goals needed for project - skipping [INFO] Setting property: classpath.resource.loader.class => 'org.codehaus.plexus.velocity.ContextClassLoaderResourceLoader'. [INFO] Setting property: velocimacro.messages.on => 'false'. [INFO] Setting property: resource.loader => 'classpath'. [INFO] Setting property: resource.manager.logwhenfound => 'false'. [INFO] [archetype:generate] [INFO] Generating project in Interactive mode [INFO] No archetype defined. Using maven-archetype-quickstart (org.apache.maven.archetypes:maven-archetype-quickstart:1.0) Choose archetype: ...... 15: internal -> maven-archetype-quickstart () ...... Choose a number: (1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/19/20/21/22/23/24/25/26/27/28/29/30/31/32/33/34/35/36/37/38/39/40/41) 15: : Define value for groupId: : com.taobao.top.appstore Define value for artifactId: : maven-test Define value for version: 1.0-SNAPSHOT: : Define value for package: com.taobao.top.appstore: : Confirm properties configuration: groupId: com.taobao.top.appstore artifactId: maven-test version: 1.0-SNAPSHOT package: com.taobao.top.appstore Y: : [INFO] ---------------------------------------------------------------------------- [INFO] Using following parameters for creating OldArchetype: maven-archetype-quickstart:RELEASE [INFO] ---------------------------------------------------------------------------- [INFO] Parameter: groupId, Value: com.taobao.top.appstore [INFO] Parameter: packageName, Value: com.taobao.top.appstore [INFO] Parameter: package, Value: com.taobao.top.appstore [INFO] Parameter: artifactId, Value: maven-test [INFO] Parameter: basedir, Value: /home/tonglin [INFO] Parameter: version, Value: 1.0-SNAPSHOT [INFO] ********************* End of debug info from resources from generated POM *********************** [INFO] OldArchetype created in dir: /home/tonglin/maven-test [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1 minute 27 seconds [INFO] Finished at: Tue Dec 22 11:33:19 CST 2009 [INFO] Final Memory: 8M/14M [INFO] ------------------------------------------------------------------------
通过archetype插件的交互操作,我们创建了一个jar项目,名字叫做maven-test
该原型默认会创建一个包含main函数的类,com.taobao.top.appstore.App,源代码如下:package com.taobao.top.appstore; /** * Hello world! * */ public class App { public static void main( String[] args ) { System.out.println( "Hello World!" ); } }
这个类很简单,如果我们想生成可执行的jar文件,需要修改MENIFEST文件,这里我们需要配置jar插件,编辑pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> ...... <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifest> <mainClass>com.taobao.top.appstore.App</mainClass> </manifest> </archive> </configuration> </plugin> </plugins> </build> ...... </project>
- 打包,创建可执行的jar文件
tonglin@tonglin-desktop:~/maven-test$ mvn package
查看jar文件的MENIFEST文件内容:
Manifest-Version: 1.0 Archiver-Version: Plexus Archiver Created-By: Apache Maven Built-By: tonglin Build-Jdk: 1.6.0_16 Main-Class: com.taobao.top.appstore.App
- 运行
tonglin@tonglin-desktop:~/maven-test$ java -jar target/maven-test-1.0-SNAPSHOT.jar Hello World!
运行成功,这个类很简单,没有任何依赖,如果我们想做些更复杂的东西,首先我们需要
- 增加依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> ...... <dependencies> ...... <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.1</version> </dependency> ...... </dependencies> ...... </project>
- 生成Eclipse文件
tonglin@tonglin-desktop:~$ cd maven-test/ tonglin@tonglin-desktop:~/maven-test$ mvn eclipse:clean eclipse:eclipse
- 打开Eclipse,编辑com.taobao.top.appstore.App
package com.taobao.top.appstore; import org.apache.commons.lang.StringUtils; /** * Hello world! * */ public class App { public static void main( String[] args ) { final String x = StringUtils.center("Hello World!", 20); System.out.println( x ); } }
- 再次打包,运行
tonglin@tonglin-desktop:~/maven-test$ mvn package tonglin@tonglin-desktop:~/maven-test$ java -jar target/maven-test-1.0-SNAPSHOT.jar Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/lang/StringUtils at com.taobao.top.appstore.App.main(App.java:13) Caused by: java.lang.ClassNotFoundException: org.apache.commons.lang.StringUtils at java.net.URLClassLoader$1.run(URLClassLoader.java:200) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:188) at java.lang.ClassLoader.loadClass(ClassLoader.java:307) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301) at java.lang.ClassLoader.loadClass(ClassLoader.java:252) at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320) ... 1 more
运行失败,抛出异常说org.apache.commons.lang.StringUtils类找不到,我们需要将org.apache.commons.lang.StringUtils,添加到类路径,修改pom.xml
- 添加类路径
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> ...... <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> <mainClass>com.taobao.top.appstore.App</mainClass> </manifest> </archive> </configuration> </plugin> </plugins> </build> ...... </project>
- 再次打包
tonglin@tonglin-desktop:~/maven-test$ mvn package
查看jar包的MENIFEST
Manifest-Version: 1.0 Archiver-Version: Plexus Archiver Created-By: Apache Maven Built-By: tonglin Build-Jdk: 1.6.0_16 Main-Class: com.taobao.top.appstore.App Class-Path: commons-lang-2.1.jar
- 运行
tonglin@tonglin-desktop:~/maven-test$ java \-jar target/maven-test-1.0-SNAPSHOT.jar Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/lang/StringUtils at com.taobao.top.appstore.App.main(App.java:13) Caused by: java.lang.ClassNotFoundException: org.apache.commons.lang.StringUtils at java.net.URLClassLoader$1.run(URLClassLoader.java:200) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:188) at java.lang.ClassLoader.loadClass(ClassLoader.java:307) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301) at java.lang.ClassLoader.loadClass(ClassLoader.java:252) at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320) ... 1 more
运行仍旧失败,那如何把依赖的源代码也打到这个jar包中呢,这个时候,maven-assembly-plugin插件就派上用场了
- 配置maven-assembly-plugin
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> ...... <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> <mainClass>com.taobao.top.appstore.App</mainClass> </manifest> </archive> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <configuration> <archive> <manifest> <mainClass>com.taobao.top.appstore.App</mainClass> </manifest> </archive> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> </plugin> </plugins> </build> ...... </project>
注意上面的jar-with-dependencies,这样就会把jar包和它的所有runtime依赖添加到一个jar包中了,
- 装配
tonglin@tonglin-desktop:~/maven-test$ mvn assembly:assembly [INFO] Scanning for projects... [INFO] Searching repository for plugin with prefix: 'assembly'. [INFO] ------------------------------------------------------------------------ [INFO] Building maven-test [INFO] task-segment: [assembly:assembly] (aggregator-style) [INFO] ------------------------------------------------------------------------ [INFO] Preparing assembly:assembly [INFO] ------------------------------------------------------------------------ [INFO] Building maven-test [INFO] ------------------------------------------------------------------------ [INFO] [resources:resources] [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory /home/tonglin/maven-test/src/main/resources [INFO] [compiler:compile] [INFO] Nothing to compile - all classes are up to date [INFO] [resources:testResources] [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory /home/tonglin/maven-test/src/test/resources [INFO] [compiler:testCompile] [INFO] Nothing to compile - all classes are up to date [INFO] [surefire:test] [INFO] Surefire report directory: /home/tonglin/maven-test/target/surefire-reports ------------------------------------------------------- T E S T S ------------------------------------------------------- Running com.taobao.top.appstore.AppTest Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.089 sec Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0添加到类路径 [INFO] [jar:jar] [INFO] Building jar: /home/tonglin/maven-test/target/maven-test-1.0-SNAPSHOT.jar [INFO] [assembly:assembly] [INFO] Processing DependencySet (output=) [INFO] Building jar: /home/tonglin/maven-test/target/maven-test-1.0-SNAPSHOT-jar-with-dependencies.jar [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------------ [INFO] Total time: 9 seconds [INFO] Finished at: Tue Dec 22 13:56:56 CST 2009 [INFO] Final Memory: 13M/24M [INFO] ------------------------------------------------------------------------
运行上面的命令,就会在target目录下生成maven-test-1.0-SNAPSHOT-jar-with-dependencies.jar
- 运行
tonglin@tonglin-desktop:~/maven-test$ java -jar target/maven-test-1.0-SNAPSHOT-jar-with-dependencies.jar Hello World!
运行成功,一切OK,如果我们想在打包阶段,自动运行assembly插件的assembly目标,那么只需少许的改动
- 打包阶段自动运行assembly
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> ...... <build> <plugins> ...... <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <configuration> <archive> <manifest> <mainClass>com.taobao.top.appstore.App</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> ...... </project>
这样,我们再次运行:
tonglin@tonglin-desktop:~/maven-test$ mvn clean package [INFO] Scanning for projects... [INFO] ------------------------------------------------------------------------ [INFO] Building maven-test [INFO] task-segment: [clean, package] [INFO] ------------------------------------------------------------------------ [INFO] [clean:clean] [INFO] Deleting directory /home/tonglin/maven-test/target [INFO] [resources:resources] [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory /home/tonglin/maven-test/src/main/resources [INFO] [compiler:compile] [INFO] Compiling 1 source file to /home/tonglin/maven-test/target/classes [INFO] [resources:testResources] [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory /home/tonglin/maven-test/src/test/resources [INFO] [compiler:testCompile] [INFO] Compiling 1 source file to /home/tonglin/maven-test/target/test-classes [INFO] [surefire:test] [INFO] Surefire report directory: /home/tonglin/maven-test/target/surefire-reports ------------------------------------------------------- T E S T S ------------------------------------------------------- Running com.taobao.top.appstore.AppTest Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.077 sec Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] [jar:jar] [INFO] Building jar: /home/tonglin/maven-test/target/maven-test-1.0-SNAPSHOT.jar [INFO] [assembly:single {execution: make-assembly}] [INFO] Processing DependencySet (output=) [INFO] Building jar: /home/tonglin/maven-test/target/maven-test-1.0-SNAPSHOT-jar-with-dependencies.jar [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------------ [INFO] Total time: 13 seconds [INFO] Finished at: Tue Dec 22 14:40:54 CST 2009 [INFO] Final Memory: 17M/34M [INFO] ------------------------------------------------------------------------
注意:上面配置package,运行的是assembly:single,而不是assembly:assembly,这两者有什么区别呢:
- assembly:assembly 这个目标会自动执行package生命周期
- assembly:single 这个目标仅会装配成jar-with-dependencies,我们不想让package阶段运行两次package,所以配置成这个
- 参考资料:
- maven-assembly-plugin:http://maven.apache.org/plugins/maven-assembly-plugin/
- maven-jar-plugin:http://maven.apache.org/plugins/maven-jar-plugin/
- 项目源代码:
- Windowd平台:maven-test.zip
- Linux平台:maven-test.tar.gz
希望这篇文章能够让有同样经历的同学,减少困惑,有任何问题请联系我!
- maven-test.tar.gz (1.3 KB)
- 下载次数: 28
- maven-test.zip (4.2 KB)
- 下载次数: 60
评论
很好的解决hadoop依赖第三方jar的问题。
楼主的step by step教程很好!
在eclipse里面直接打包,还可以用fatjar插件。
不过有一个问题: 装配完的jar名字除正常的外,还带了一个“...jar-with-dependencies.jar”, 请问下这个去掉?
不好意思,时到今日,才看到你的回复,可能你自己已经解决了这个问题,但是我还是把答案告诉你吧,也可以帮助其他有同样问题的同学。
其实这个问题很简单,只需要在assembly的configure节点加上appendAssemblyId,值为false,即:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <configuration> <appendAssemblyId>false</appendAssemblyId> <archive> <manifest> <mainClass>com.taobao.top.appstore.App</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>
不过有一个问题: 装配完的jar名字除正常的外,还带了一个“...jar-with-dependencies.jar”, 请问下这个去掉?
发表评论
-
MemCached基础
2009-07-21 18:58 4099MemCached是什么? MemCached是一个高性能、 ... -
MemCache深入浅出
2009-07-20 18:55 0本文主要讲述的memcached的概念,安装、监控、分布式算法 ... -
编码最佳实践系列之二
2008-10-23 11:35 1251Map的迭代,使用map的entrySet,不用使用keyS ... -
编码最佳实践系列之一
2008-10-23 11:28 1229避免空指针: /** * 判断应用是否有月租 * ... -
编码中日志使用规范
2008-10-23 11:19 1761编码中请统一使用commons-logging包 日志声明 ... -
PMD 规则集——Optimization Rules
2008-09-03 11:18 4180Optimization Rules优化规则 These ... -
PMD
2008-09-01 14:23 2075PMD 扫描Java源代码并且寻找潜在的问题像: 可能存在的 ...
相关推荐
Java档案文件(JAR)是Java平台上的一个重要概念,它允许开发者将多个类文件、资源文件以及元数据打包成一个单一的...通过理解JAR文件的工作原理和创建可执行JAR的方法,开发者能够更好地管理和分享他们的Java项目。
### 生成可执行JAR文件的详细教程 #### 一、引言 在Java开发过程中,经常需要将项目打包成可执行的JAR文件,以便于分发和部署。本教程将详细介绍如何通过CMD命令行生成一个可执行的JAR文件。 #### 二、准备工作 在...
1. **MANIFEST.MF文件**:在创建可执行JAR时,需要一个名为`MANIFEST.MF`的特殊文件,它包含主类信息。主类是程序启动时执行的第一个类。例如,`Main-Class: com.example.MyApp`告诉Java哪个类是程序的入口点。 2. ...
### Java入门:生成可执行JAR文件的详细教程 #### 标题与描述解析 本教程旨在引导初学者了解如何生成可执行的JAR文件,从而掌握Java的基础编程技能。对于初学者而言,掌握如何打包自己的Java程序为一个可执行的JAR...
以下是生成可执行JAR文件的详细步骤和相关知识点: 1. **理解JAR文件**: JAR文件是Java平台的标准归档格式,用于存储编译后的Java类文件、元数据和资源文件。它们通过.zip格式进行压缩,方便分发和部署。JAR文件...
制作可执行的JAR文件包及jar命令详解 Java Archives(JAR)文件是一种Java特有的文档格式,类似于ZIP文件,但包含了一个META-INF/MANIFEST.MF文件,该文件是在生成JAR文件时自动创建的。JAR文件可以包含Java类、...
### Eclipse 项目打包成可执行JAR文件详解 在Java开发过程中,经常需要将开发完成的应用程序打包成可执行的JAR文件以便于部署和分发。本文将详细介绍如何使用Eclipse IDE将Java项目打包成可执行的JAR文件。 #### ...
"Eclipse制作可执行jar文件" 使用Eclipse制作可执行jar文件是初学者用户的需求之一。以下是详细的步骤和知识点: 一、Eclipse项目导出可执行jar文件 在Eclipse中,右击项目,选择Export,然后选择Java -> JAR ...
创建可执行JAR文件 为了使JAR文件可执行,需要在其中的`MANIFEST.MF`文件中添加特定的属性,比如`Main-Class`,该属性指定了JAR文件启动时的主类。 - **创建JAR文件命令示例**: ```plaintext C:\test>jarcvf ...
为了解决这个问题,可以将JAR文件转换为Windows操作系统下的可执行文件(EXE),使得用户只需双击就能运行程序,无需预先安装Java环境。 转换JAR到EXE的过程主要涉及以下步骤和相关知识点: 1. **理解JAR和EXE的...
本文将深入探讨如何使用Java自带的`jar`工具来创建可执行的JAR文件,并对`jar`命令进行详细解析。 #### 一、JAR文件概念 JAR文件是一种遵循ZIP文件格式标准的归档文件,但与普通的ZIP文件不同的是,它包含了一个名...
**创建可执行JAR文件** 为了使JAR文件成为可执行文件,开发者需要在`MANIFEST.MF`中添加`Main-Class`字段,指定程序的入口点(即包含`public static void main(String[] args)`方法的类)。例如,如果主类位于`test`...
以下是两种在MyEclipse中生成可执行JAR文件的方法: ### 无外部依赖的JAR文件 当你的Java项目没有引用任何外部的JAR包时,生成可执行JAR文件的过程相对简单。在MyEclipse中,你可以按照以下步骤操作: 1. 打开...
创建可执行JAR文件的关键步骤包括: 1. **编写主类**:首先,你需要编写包含`public static void main(String[] args)`方法的主类。这个方法是Java程序的入口点,当JAR文件被执行时,该方法会被调用。 2. **创建...
下面我们将详细探讨如何按照标题“以包创建可执行JAR1”的描述,完成这个过程。 首先,我们需要理解Java项目的基本结构。在Java中,我们通常使用包(package)来组织源代码,以便于管理类和防止命名冲突。例如,...
4. **设置manifest文件**:manifest文件包含了关于Jar文件的信息,如主类(如果该Jar文件是一个可执行的Java应用)。在导出向导的“Manifest”选项卡中,你可以添加或编辑manifest文件,指定主类(Main-Class属性)...