在JAR中打包使用JAR库

不知大家在写Java程序的时候有没有这样的需求: 将引用其它第三方JAR库的项目打包成一个JAR文件运行.也就是说在你打包好的JAR文件中再包含那些你引用的第三方JAR文件,合成一个JAR包,这样只需在Windows下双击,或在Linux终端下输入 java -jar yourjarfile.jar即可方便运行.在最初一种普遍的做法是在打包的JAR文件中的META-INF/MANIFEST里使用Class-Path选项,像这样:

Manifest-Version: 1.0
Created-By: 1.7.0_06-b24 (Oracle Corporation)
Main-Class: YOUR.MAIN.CLASS.NAME.HERE
Class-Path: lib1.jar lib2.jar lib3.jar

但这样在运行这个JAR包时仍然需要将引用的lib1.jar,lib2.jar,lib3.jar放入你打包的JAR文件目录中.即使你将其打包进你的JAR包中,仍不可以独立运行.

以前这样打包的问题一直困扰着我,难道在Java中就不能像exe打包程序那样一个文件单独跑吗?

直到今天再次遇到这个问题时,GOOGLE了一下找到了一个不错的解决方案.就是使用第三方工具包One-Jar.对应下载地址:http://sourceforge.net/projects/one-jar/

使用One-Jar非常的简单.只需要简单的几步,但在使用One-Jar之前需要事先自行将自己的项目使用jar命令打包成JAR包,其中不包括三方JAR包,再进行如下操作:

1.创建一个名为"root"的工作目录,其中在包含两个名为"main"和"lib"的子目录;

2.顾名思意,这里root/main用于存放你自己已经打包好了的JAR文件,并将它改名为main.jar,注意在打包你的class文件时,不要包含任何你引用的JAR包.而对应的root/lib才用来存放那些你引用的第三方JAR包.

3.从One-Jar官网中下载最新的One-Jar包.并将它解压放入到root目录中,对应的重名目录合并.同时去掉"src"目录.(注意在解包One-Jar时的隐藏文件).

4.再在root目录中新建一个名为boot-manifest.mf的文件,其内容如下:

Manifest-Version: 1.0
Main-Class: com.simontuffs.onejar.Boot
One-Jar-Main-Class: YOUR.MAIN.CLASS.NAME.HERE

5.最后一步,在命令行下输入cd root进入root目录,然后运行java的打包命令如下:

jar -cvfm ../你的程序名.jar boot-manifest.mf .

运行后,如果一切顺利,则会在root目录的上层目录中生成"你的程序名.jar"的文件,这时在windows环境中,你只需要双击这个文件则可以运行启动你的程序.就这样的一个文件,非常的给力!哈哈

在进行One-Jar的打包时一定要注意它的对应目录结构,如下给出root目录详细的结构说明:

root目录
|  .version
|  one-jar-$project$.jar
|  OneJar.class
|  boot-manifest.mf          # 你新建的boot-manifest.mf
|  com/simontuffs/onejar     # One-Jar的源文件目录
   |  Boot.class, ...etc.
|  doc/one-jar-license.txt   # 对应的软件协议
|  main/main.jar             # 你的程序JAR
|  lib/a.jar ...etc.         # 你程序依赖的第三方JAR包

如果一切都是按照上面的目录结构来的,应该就不会有问题.其实One-Jar不仅可以单独使用,还可以与Ant与Meavn等Java项目源码管理软件结合使用,在这里就不细说了(哈哈, 关键是我没有试~),感兴趣可以到http://one-jar.sourceforge.net/index.php?page=getting-started&file=quickstart处查看.

条条道路通罗马,不仅仅One-Jar可以,我还查了一下,还有UberJarShade也具有同样的功能.只不过它俩好像还需要依赖Maven.对应stackoverflow上大神的原话(处出:http://stackoverflow.com/questions/183292/classpath-including-jar-within-a-jar):

If you‘re trying to create a single jar that contains your application and it‘s required libraries, there are two ways (that I know of) to do that. The first is One-Jar, which uses a special classloader to allow the nesting of jars. The second is UberJar,
(or Shade), which explodes the included libraries and puts all the classes in the top-level jar.I should also mention that UberJar and Shade are plugins for Maven1 and Maven2 respectively. As mentioned below, you can also use the assembly plugin (which in
reality is much more powerful, but much harder to properly configure).

关于Java启动器为什不能使用Class-Path加载JAR包里面的JAR库,也在stackoverflow上找到了对应的解释说明(出处:http://stackoverflow.com/questions/12357136/reference-jars-inside-a-jar),如下:

The Java Launcher$AppClassLoader does not know how to load classes from a Jar inside a Jar with this kind of Class-Path. Trying to use jar:file:jarname.jar!/commons-logging.jar also leads down a dead-end.
This approach will only work if you install (i.e. scatter) the supporting Jar files into the directory where the jarname.jar file is installed.

最后关于One-Jar的原理的一点小小的猜想:我想就是使用Java库中的某个工具类,先事强制加载指定目录的JAR包于内存.然后使用反射机制调用META-INF/MANIFEST文件中One-Jar-Main-Class项指定类的main方法,实现程序启动的目地的吧.而具体怎么实现就要好好的研究One-Jar的源码了~

在JAR中打包使用JAR库,布布扣,bubuko.com

时间: 2024-12-24 23:15:22

在JAR中打包使用JAR库的相关文章

eclipse导出jar(java打包导出jar)

有时候需要将j2se工程导出,这样可以在别处运作,就不必拘泥于开发感觉中才能运行了.具体做法如下:方法一:(工程没有引用外部jar包时,直接导出) 选中工程---->右键,Export...--->Java--->JAR file--->next-->选择jar file的路径及名称-->next-->next---> 选择main class--->finish. 方法2: 当工程引用了其他的外部jar时,由于eclipse不支持同时导出外部jar包

[Java基础] 深入jar包:从jar包中读取资源文件

转载: http://hxraid.iteye.com/blog/483115?page=3#comments 我们常常在代码中读取一些资源文件(比如图片,音乐,文本等等).在单独运行的时候这些简单的处理当然不会有问题.但是,如果我们把代码打成一个jar包以后,即使将资源文件一并打包,这些东西也找不出来了.看看下面的代码: //源代码1: package edu.hxraid; import java.io.*; public class Resource { public void getRe

命令行下Jar包打包小结

jar包打包实现 第一种简单的打包方式 第二种打包方式 MANIFEST文件介绍 小结 jar包打包实现 jar包打包可以使用jar指令实现打包,在命令行中输入jar可以查看jar指令的内容 从最后显示的两个示例看出存在两种打包的方法,两者的区别就是是否使用自己定义的MANIFEST清单文件.第一个示例没有使用MANIFEST文件进行打包,所以最终生成的jar包中MANIFEST文件为默认文件,这种方式适用于比较简单的jar包结构,不存在其他jar包依赖以及生成的jar包不需要可执行.这种方式生

SpringBoot引入第三方jar包或本地jar包的处理方式

在开发过程中有时会用到maven仓库里没有的jar包或者本地的jar包,这时没办法通过pom直接引入,那么该怎么解决呢 一般有两种方法 第一种是将本地jar包安装在本地maven库 第二种是将本地jar包放入项目目录中 这篇文章主要讲第二种方式,这又分两种情况,一种是打包jar包,第二种是打包war包 jar包 先看看jar包的结构 用压缩工具打开一个jar包 打包后jar包的路径在BOOT-INF\lib目录下 在项目目录中创建个文件夹用来存放jar包 pom文件中加入如下内容 <depend

使用Gradle将Maven库打包成Jar

项目需要将Dropwizard(Java RESTful服务)与Derby(轻量数据库)打包成Jar然后提供给其他工程使用,由于Dropwizard并未提供jar-release版本,所以写了个gradle构建脚本用于将maven库中的Dropwizard与Derby整合打包成一个jar包,然后再添加到目标项目中使用. 脚本代码: apply plugin: 'java' project.ext { // 项目标题名称 title = 'DropwizardDerby' // 项目名称前缀 ba

有关打包成可执行jar包后引用jar包中配置文件问题

一 问题由来 有时候我们做一些项目时,需要将一些配置信息写入配置文件中,以供调用.比如说这样: 如果我们需要在Demo.java中读取config.txt这个文件中的配置信息,在这种工程目录下是可以使用File来读取的,但是打包成jar后,使用File将不能读取到config.txt了,除非将这个配置信息放在jar包的外面. 假如说我们用File来读取文件: BufferedReader reader = new BufferedReader(new FileReader(new File("r

Java如何将图片打包到jar中

Eclipse使用导出Jar包后打开加载不了图像 ?????? 出现这种问题的原因大多是因为路径的问题,往往是在项目中运行正常,但是一旦打包成Jar后就不能正常显示了,下面总结一下解决此类问题的方法: 一.通过使用外部资源文件的方式解决 把项目打包生成Jar后,再新建一文件夹,把项目中所有使用的图片文件和生成Jar文件放在该目录下,只要代码对图片文件的引用路径正确,如:ImageIconimage=newImageIcon(SwingResourceManager.getImage("icons

Eclipse项目中引用第三方jar包时将项目打包成jar文件的两种方式

转载自:http://www.cnblogs.com/lanxuezaipiao/p/3291641.html 方案一:用Eclipse自带的Export功能 步骤1:准备主清单文件 “MANIFEST.MF”, 由于是打包引用了第三方jar包的Java项目,故需要自定义配置文件MANIFEST.MF,在该项目下建立文件MANIFEST.MF,内容如下: Manifest-Version: 1.0 Class-Path: lib/commons-codec.jar lib/commons-htt

【hadoop】 eclipse中的“run on hadoop”和打包成jar提交任务的区别

eclipse中的 调试运行 及 “run on hadoop”默认只是运行在单机上的,因为要想在集群中让程序分布式运行还要经历上传类文件.分发到各个节点等过程, 一个简单的“run on hadoop”只是启动了本地hadoop类库来运行你的程序而已, 在Hadoop cluster的web管理页面(http://192.168.2.2:8088/cluster/apps)上是看不到任何作业信息的,因为你的作业根本就没有运行在集群上. 打包成jar方法: rm tmp/* cp xmlpars