Java世界一个很难绕过的问题就是依赖包,绝大部分项目总会或多或少的依赖第三方包。Maven或者Gradle等可以帮助我们轻松的管理第三方依赖,但是对于自己对外提供的包,特别是作为中间件或者基础组件等提供出去的包,还是会遇到一些第三方依赖的问题,主要有两个问题
第一个情况可以先打一个fatjar,然后通过ProGuard精简代码。
第二个情况就需要把第三方包的代码拷贝到自己的包中,在自己的代码中直接使用拷贝进来的三方包代码(pakcage name不一样),这样就可以最大程度保证稳定性。
当然大部分情况下对于第三方包的版本依赖没有那么敏感,上面说到的情况其实是大部分针对asm,cglib和objenesis等几个字节码增强的包。
具体的操作可以借助jarjar工具,先将三方包重新打包,然后修改Gradle的Jar任务,将重新打包后的jar复制到自己的包中。
task cglibRepackJar(type: Jar) { repackJar -> repackJar.baseName = "cglib-repack" repackJar.version = cglibVersion doLast() { project.ant { taskdef name: "jarjar", classname: "org.pantsbuild.jarjar.JarJarTask", classpath: configurations.jarjar.asPath jarjar(destfile: repackJar.archivePath) { configurations.cglib.each { originalJar -> zipfileset(src: originalJar) } // Repackage net.sf.cglib => com.huangyunkun.cglib rule(pattern: "net.sf.cglib.**", result: "com.huangyunkun.cglib.@1") // As mentioned above, transform cglib's internal asm dependencies from // org.objectweb.asm => com.huangyunkun.asm. Doing this counts on therule(pattern: "org.objectweb.asm.**", result: "com.huangyunkun.asm.@1") } } } }
然后修改Gradle的Jar任务配置
jar { dependsOn cglibRepackJar from(zipTree(cglibRepackJar.archivePath)) { include "com/huangyunkun/cglib/**" } }
当然在具体打包的时候还可以根据需要exclude一些不需要的模块。
参考:https://github.com/shevek/jarjar