jarjar:方便的java打包工具

14 篇文章 0 订阅
5 篇文章 0 订阅

今天为打包java代码破费周折,最好在stackoverflow上有人提议用jarjar包,下载下来后发现非常好用,所以就想把这个过程记录下来,但是在google上敲入jarjar之后发现了下面这篇文章,讲的很详细,于是索性转载过来。原帖网址为:http://blog.cogipard.org/articles/java-library-repackage-tool-jarjar

项目主页在Google Code上:http://code.google.com/p/jarjar/
有没有碰到这么一种情况,在开发项目的时候,为了避免“JAR hell”,为了更好的管理项目依赖,需要将别的java项目的jar包重新打包到我们自己现有的项目中来,比如把包org.apache.commons.logging打包成repackaged.org.apache.commons,你会怎么办?手工改显然费时费力,不仅要改变每个类的package声明,还要改变自己项目中所有使用了commons-logging类的代码。那么jarjar就是为了干这件事而专门定做的工具。

代码重新打包工具jarjar可以帮助你将其它用到的java库打包并嵌入到你自己的项目jar包中。这样做的原因有:

  • 当你发布项目的时候,把用到的库打包进现有项目jar包,可以让发布的这个jar包不比依赖于其它项目的jar包;
  • 当你所用到的java库升级了以后,它所新发布的jar包可能和你现存的项目不匹配,为了保持项目的代码稳定性,你可以把编写代码时所用到的依赖jar包,全部打包进现在的项目jar包,以避免出现这个问题。

jarjar可以通过Ant任务的方式使用,也可以单独地在命令行下使用。打包代码时,如果你要重命名某些依赖包的名字的时候,jarjar会调用字节码转换(通过ASM)来更新代码,并自动做好其他工作。

以Ant任务的形式使用jarjar

我们现存的Ant任务里可以用jar任务来打包代码,比如:

XML
1
2
3
4
5
  1. <span style="color:rgb(0,153,0)"><strong><target</strong> <span style="color:rgb(0,0,102)">name</span>=<span style="color:rgb(255,0,0)">"jar"</span> <span style="color:rgb(0,0,102)">depends</span>=<span style="color:rgb(255,0,0)">"compile"</span><strong>></strong></span>  
  2.     <span style="color:rgb(0,153,0)"><strong><jar</strong> <span style="color:rgb(0,0,102)">jarfile</span>=<span style="color:rgb(255,0,0)">"dist/example.jar"</span><strong>></strong></span>  
  3.         <span style="color:rgb(0,153,0)"><strong><fileset</strong> <span style="color:rgb(0,0,102)">dir</span>=<span style="color:rgb(255,0,0)">"build/main"</span><strong>/></strong></span>  
  4.     <span style="color:rgb(0,153,0)"><strong></jar<strong>></strong></strong></span>  
  5. <span style="color:rgb(0,153,0)"><strong></target<strong>></strong></strong></span>  

为了使用jarjar工具,我们创建一个叫jarjar的任务,由于JarJarTask是Ant标准任务Jar的子类,所以如果你不需要使用jarjar的特有功能的话,完全可以像这样调用jarjar工具:

XML
1
2
3
4
5
6
7
  1. <span style="color:rgb(0,153,0)"><strong><target</strong> <span style="color:rgb(0,0,102)">name</span>=<span style="color:rgb(255,0,0)">"jar"</span> <span style="color:rgb(0,0,102)">depends</span>=<span style="color:rgb(255,0,0)">"compile"</span><strong>></strong></span>  
  2.     <span style="color:rgb(0,153,0)"><strong><taskdef</strong> <span style="color:rgb(0,0,102)">name</span>=<span style="color:rgb(255,0,0)">"jarjar"</span> <span style="color:rgb(0,0,102)">classname</span>=<span style="color:rgb(255,0,0)">"com.tonicsystems.jarjar.JarJarTask"</span></span>  
  3. <span style="color:rgb(0,153,0)">        <span style="color:rgb(0,0,102)">classpath</span>=<span style="color:rgb(255,0,0)">"lib/jarjar.jar"</span><strong>/></strong></span>  
  4.     <span style="color:rgb(0,153,0)"><strong><jarjar</strong> <span style="color:rgb(0,0,102)">jarfile</span>=<span style="color:rgb(255,0,0)">"dist/example.jar"</span><strong>></strong></span>  
  5.         <span style="color:rgb(0,153,0)"><strong><fileset</strong> <span style="color:rgb(0,0,102)">dir</span>=<span style="color:rgb(255,0,0)">"build/main"</span><strong>/></strong></span>  
  6.     <span style="color:rgb(0,153,0)"><strong></jarjar<strong>></strong></strong></span>  
  7. <span style="color:rgb(0,153,0)"><strong></target<strong>></strong></strong></span>  

就像标准的”jar”任务一样,可以通过”zipfileset”元素来包含其它jar包。但是仅仅包含其它jar包并不能让你远离“jar包陷阱”,因为你所依赖的jar包中的类名还是没有改变,仍然有可能和其它版本的jar包里的类名相同,产生冲突。
为了重命名类名,JarJarTask引入了一个新元素”rule”。”rule”包含了”pattern”属性,你可以通过这个属性,使用通配符来选择哪些类需要重命名,通过”result”属性可以设置如何给选中的类重命名。

在本例中我们希望引入一个叫jaxen.jar的库。并将所有以”org.jaxen”开头的类重命名以”org.example.jaxen”开头:

XML
1
2
3
4
5
6
7
8
9
  1. <span style="color:rgb(0,153,0)"><strong><target</strong> <span style="color:rgb(0,0,102)">name</span>=<span style="color:rgb(255,0,0)">"jar"</span> <span style="color:rgb(0,0,102)">depends</span>=<span style="color:rgb(255,0,0)">"compile"</span><strong>></strong></span>  
  2.     <span style="color:rgb(0,153,0)"><strong><taskdef</strong> <span style="color:rgb(0,0,102)">name</span>=<span style="color:rgb(255,0,0)">"jarjar"</span> <span style="color:rgb(0,0,102)">classname</span>=<span style="color:rgb(255,0,0)">"com.tonicsystems.jarjar.JarJarTask"</span></span>  
  3. <span style="color:rgb(0,153,0)">        <span style="color:rgb(0,0,102)">classpath</span>=<span style="color:rgb(255,0,0)">"lib/jarjar.jar"</span><strong>/></strong></span>  
  4.     <span style="color:rgb(0,153,0)"><strong><jarjar</strong> <span style="color:rgb(0,0,102)">jarfile</span>=<span style="color:rgb(255,0,0)">"dist/example.jar"</span><strong>></strong></span>  
  5.         <span style="color:rgb(0,153,0)"><strong><fileset</strong> <span style="color:rgb(0,0,102)">dir</span>=<span style="color:rgb(255,0,0)">"build/main"</span><strong>/></strong></span>  
  6.         <span style="color:rgb(0,153,0)"><strong><zipfileset</strong> <span style="color:rgb(0,0,102)">src</span>=<span style="color:rgb(255,0,0)">"lib/jaxen.jar"</span><strong>/></strong></span>  
  7.         <span style="color:rgb(0,153,0)"><strong><rule</strong> <span style="color:rgb(0,0,102)">pattern</span>=<span style="color:rgb(255,0,0)">"org.jaxen.**"</span> <span style="color:rgb(0,0,102)">result</span>=<span style="color:rgb(255,0,0)">"org.example.@1"</span><strong>/></strong></span>  
  8.     <span style="color:rgb(0,153,0)"><strong></jarjar<strong>></strong></strong></span>  
  9. <span style="color:rgb(0,153,0)"><strong></target<strong>></strong></strong></span>  

通配符**表示匹配循环所有的子包,如果你只希望匹配一个子包的话,可以使用*。
@1表示第一个**所匹配到的内容,一次类推,@2表示从左到右第二个所匹配到的*或**。@0是特殊的标志,它代表整个匹配到的类的全名。

命令行下单独使用jarjar

java -jar jarjar.jar [help]
打印帮助信息。

java -jar jarjar.jar strings 
打印类路径classpath下的字符串信息,如果类中有debug信息的话,会打印出所在行的行号。
比如java -jar jarjar.jar strings servlet-api.jar会打印:

JAVA
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  1. ...  
  2. <span style="color:rgb(0,102,51)">javax</span>.<span style="color:rgb(0,102,51)">servlet</span>.<span style="color:rgb(0,102,51)">http</span>.<span style="color:rgb(0,102,51)">HttpServletRequest</span>  
  3.     <span style="color:rgb(0,0,255)">"BASIC"</span>  
  4.     <span style="color:rgb(0,0,255)">"FORM"</span>  
  5.     <span style="color:rgb(0,0,255)">"CLIENT_CERT"</span>  
  6.     <span style="color:rgb(0,0,255)">"DIGEST"</span>  
  7. javax.<span style="color:rgb(0,102,51)">servlet</span>.<span style="color:rgb(0,102,51)">http</span>.<span style="color:rgb(0,102,51)">HttpUtils</span>  
  8.     <span style="color:rgb(0,0,255)">"javax.servlet.http.LocalStrings"</span>  
  9.     <span style="color:rgb(204,102,204)">88</span><span style="color:rgb(51,153,51)">:</span> <span style="color:rgb(0,0,255)">"javax.servlet.http.LocalStrings"</span>  
  10.     <span style="color:rgb(204,102,204)">339</span><span style="color:rgb(51,153,51)">:</span> <span style="color:rgb(0,0,255)">"://"</span>  
  11.     <span style="color:rgb(204,102,204)">341</span><span style="color:rgb(51,153,51)">:</span> <span style="color:rgb(0,0,255)">"http"</span>  
  12.     <span style="color:rgb(204,102,204)">341</span><span style="color:rgb(51,153,51)">:</span> <span style="color:rgb(0,0,255)">"https"</span>  
  13.     <span style="color:rgb(204,102,204)">145</span><span style="color:rgb(51,153,51)">:</span> <span style="color:rgb(0,0,255)">"&amp;"</span>  
  14.     <span style="color:rgb(204,102,204)">238</span><span style="color:rgb(51,153,51)">:</span> <span style="color:rgb(0,0,255)">"err.io.short_read"</span>  
  15.     <span style="color:rgb(204,102,204)">254</span><span style="color:rgb(51,153,51)">:</span> <span style="color:rgb(0,0,255)">"8859_1"</span>  
  16. ...  

java -jar jarjar.jar find []
打印出类路径下java类对类路径下类的依赖,如果省略了,那么用代替。只能取class或者jar,前者代表打印各个类之间的依赖情况,后者会打印包对包之间的依赖。

java -jar jarjar.jar process 
将按照文件所指定的方法转换到里,中原有的类将被删除。
文件的写法下面将会提到。

类路径Classpath的格式
类路径classpath是用逗号或分号(具体是那种分隔符依赖操作系统)隔开的一组目录,jar包或者zip包。详细说明请看classpath的java doc。也可以使用通配符的方式来书写classpath:http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6268383。

Rules规则文件格式
Rules规则文件是实际上一种文本文件,每一行代表一条规则Rule,行首和行末的空格会被忽略掉,有三种不同样式的Rule写法:

JAVA
1
2
3
  1. rule <span style="color:rgb(51,153,51)"><</span>pattern<span style="color:rgb(51,153,51)">></span> <span style="color:rgb(51,153,51)"><</span>result<span style="color:rgb(51,153,51)">></span>  
  2. zap <span style="color:rgb(51,153,51)"><</span>pattern<span style="color:rgb(51,153,51)">></span>  
  3. keep <span style="color:rgb(51,153,51)"><</span>pattern<span style="color:rgb(51,153,51)">></span>  

第一个是用来设置jarjar如何重命名类文件的。所有类,只要它引用到了需要改变名字的类,其相关内容就会被自动同步改变,保证不会出现引用错误。如果一个类匹配了不同的rule,只有第一个匹配的rule会生效。 和的设定同上面讲过的Ant中一样。
zap规则中 所匹配的类将会不加入生成的新jar包。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值