背景介绍
有的时候, 我们调试运行一个带了很多 jar 包的Java程序时,通过日志等方式发现一些感兴趣的信息,但无法定位具体的代码位置。比如我在维护一个转交过来的老项目代码(原有开发者都找不到了。。。)时遇到如下情况:xwork中通过 Interceptor 进行了登录拦截,因为是使用debug服务器,在访问任何页面时都会提示验证登录失败,并输出验证失败的日志,但不清楚具体是哪个jar包中的哪个类起的作用。这个时候就希望能 在项目所有jar包代码中搜索指定关键字。但各种IDE(Eclipse/IDEA) 好像没有这个功能,而且网上也没有类似资料。通过研究,发现以下方式能帮助我解决问题,特记下并共享。
解决方案
1.没有源码的jar包
在老的项目中,采用直接拷贝 jar 包到lib目录下的方式,往往很难找到对应的源码,这个时候最好的方式就是将 jar 包进行反编译得到源码,然后即可通过 fgrep 等进行搜索。
Java的反编译工具比较多,比较出名的有 jd(带GUI), 不过似乎已经很久没有更新了,因此我使用的是 procyon. 将其下载到指定目录下后(我放在 /usr/local/lib/中),执行以下命令即可将当前目录下的全部 jar 包反编译到 src 目录下。
ls -a *.jar | xargs -n1 java -jar /usr/local/lib/procyon-decompiler-0.5.30.jar -o src
2.通过maven管理的,有源码的包
现在很多新的项目都用maven或gradle一类的工具来管理依赖,大大简化了程序员的工作。其中mvn可以使用 dependency 插件的 copy-dependencies 目标拷贝依赖jar包到 target/dependency 目录下;通过 sources 目标下载源码,但默认下载地址是放在本地 response 中的 jar 旁边,比较分散,难以统一搜索。以上两个goal都不满足我的需求。想通过学习该插件源码,自己实现一个 copy-sources 目标来满足我的要求。在学习源码的过程中,发现可以通过以下命令将所有解析出来的依赖包源码下载并拷贝到指定位置(target/sources 目录下),就不用再自己实现了。
mvn dependency:copy-dependencies -Dclassifier=sources -DoutputDirectory=target/sources
执行以上命令后,再执行如下命令即可将其全部解压,然后即可进行搜索。
ls -a *.jar | xargs -n1 jar -xvf
补充说明
虽然以上的方法能解决我的问题,不过需要脱离IDE,感觉不是很方便,以后有时间时希望能学习一下通过编写IDE插件来实现正真的全局搜索。