java项目反编译

反编译

有一段时间没有写了,生病了一段时间,再加上过年,就不怎么想写了。今天记录一下工作中在弄的一个事儿,和遇到的一些问题。
做开发的都知道,自己写的java文件需要编译成class文件之后才能执行,反编译的话肯定就是从class文件恢复成java文件,为什么这么做呢,因为git管理的源码和生产服务器上的代码不一致,所以需要将生产机器上的class文件进行反编译,和git上管理的代码进行比对,最终彻底解决这个问题。
反编译有很多工具,idea中自带的插件fernFlower,jdk也自带了反编译命令,包括我用的Luyten这个工具,有挺多的,我主要调研了五个,我简单总结了一下:

(1) Jdk自带的反编译命令:不可取,反编译之后不是java文件,更像是你可以看懂的语法,校对成本高。
(2) Jad工具:一个比较老的Java反编译工具,可以针对单个class文件进行反编译,但是不支持java8中lamda表达式等语法,目前项目中使用的是jdk8,所以无法使用。
(3) Idea自带的插件FernFlower:该工具是反编译效果最好的一个,但是没有找到对单独的class文件反编译的方式,只能针对整个jar来进行操作,所以无法使用
(4) Jd-gui:该工具和FernFlower存在一样的问题就是无法对单个class文件进行反编译,所以无法使用
(5) Luyten:最终找到了这个工具,支持对单个class文件进行反编译,也支持对java8中lamda表达式等语法,反编译效果和原代码略有区别(无法反编译中文,需要通过Unicode编码再转成中文,还有一些语法中的调整),在本地测试效果还行,没有用生产服务器上的class文件测试。不知道最终效果如何

最终也是通过大学同学(李 * 亮)的帮助下,用第五个工具解决了我需要反编译的问题,如果有需要这个工具的可以私聊我,我懒得弄网盘什么的了,这个工具转换成java文件之后,中文会变成unicode码,这个需要自己去再转成中文,另外代码中会有很多不必要的类型转换,虽然无伤大雅,但是看着难受。

jar包管理问题

最开始让我评估这个工作的时候,我想的有点简单了,想着不就是把class文件反编译成java文件然后启动,测试就行了,但是在我启动的时候另一个问题出现了,由于这个项目之前都是手动维护classes和lib包,所以没什么问题,但是如果反编译之后就要全量替换classes和lib包,全量替换lib包这时候就出现问题了。
出现了大量的依赖冲突问题,主要就是大量的NoSuchMethod异常,为什么这样呢,因为这些jar包里有很多包路径和类名完全相同的类,而tomcat在进行类加载的时候包名和类名完全相同的时候只会加载一个,所以如果加载的那个类不是你项目里需要的当然在这个类中找不到对应的方法了,这是根本原因。
我主要采用两种办法解决:
1.在pom文件种排除存在冲突的jar包
2.在进行类加载的时候,指定它加载我需要的那个jar包中的类
java的类加载机制事双亲委派机制,java自带的三个加载器,BootstrapClassLoader,ExtentionClassLoader,applicationClassLoader,这三个的层级依次递减,自己可以自定义一个类加载器来解决这个问题
这里我用了另一个方法,在搜索解决方案的时候看到有的博客里提到了tomcat加载jar包的顺序,如果优先加载我需要的jar包,不也可以解决这个问题了么,简单了解一下,tomcat7版本加载jar包的顺序是通过jar包名的字母顺序,但是tomcat8加载jar包的顺序竟然是随机的,竟然同一台机器在不同时刻加载jar包的顺序都不一定。很不幸,我这个项目用的就是tomcat8,但是也同时提供了解决办法,在tomcat安装路径下 conf/context.xml这个配置文件里可以配置PreSource来告诉tomcat8优先加载哪个jar包,具体看下面:

 <Resources>
   <PreResources className="org.apache.catalina.webresources.FileResourceSet"
                 base="/***/***/***/***/webapps/***/WEB-INF/lib/jackson-databind-2.16.1.jar"
                 webAppMount="/WEB-INF/lib/jackson-databind-2.16.1.jar" />

   <PreResources className="org.apache.catalina.webresources.FileResourceSet"
                 base="/***/***/***/***/webapps/***/WEB-INF/lib/logback-classic-1.2.12.jar"
                 webAppMount="/WEB-INF/lib/logback-classic-1.2.12.jar" />

   <PreResources className="org.apache.catalina.webresources.FileResourceSet"
                 base="/***/***/***/***/webapps/***/WEB-INF/lib/logback-core-1.2.12.jar"
                 webAppMount="/WEB-INF/lib/logback-core-1.2.12.jar" />

   <PreResources className="org.apache.catalina.webresources.FileResourceSet"
                 base="/***/***/******/******/webapps/******/WEB-INF/lib/hadoop-common-3.3.6.jar"
                 webAppMount="/WEB-INF/lib/hadoop-common-3.3.6.jar" />

 </Resources>

星号换成所在机器中具体的jar包位置

写这么多吧,写的比较干,见谅!

是不是一定要有所失,才能有所悟

  • 21
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值