修改Jar内容

例子

最近线上报了一个java.lang.UnsatisfiedLinkError的错误,发现环信内部没有将某个loadLibrary方法try catch(error),但是其内部的_loadLibrary方法是try catch(error)的,所以准备做以下修改:
hyphenatechat_3.4.2.jar中的EMClient.class文件中的loadLibrary方法做以下替换:

private static void loadLibrary() {
    if (!libraryLoaded) {
        _loadLibrary("sqlite");
        _loadLibrary("hyphenate_av");
        _loadLibrary("hyphenate_av_recorder");
        System.loadLibrary("hyphenate");
        libraryLoaded = true;
    }

}

替换为

private static void loadLibrary() {
    if (!libraryLoaded) {
        _loadLibrary("sqlite");
        _loadLibrary("hyphenate_av");
        _loadLibrary("hyphenate_av_recorder");
        _loadLibrary("hyphenate");
        libraryLoaded = true;
    }

}

环境

Windows

需要下载内容

使用步骤

  1. 依赖javassist Jar;
  2. 使用jar xvf oldJar.jar命令解压缩oldJar到当前目录下;
  3. 编写代码;
  4. 使用jd-gui验证newClass文件是否正确;
  5. 使用jar cvfm META-INF\MANIFEST.MF newJar.jar *命令将当前目录下的所有文件压缩成newJar,并且使用环信生成的MANIFEST.MF;
  6. 用newJar替换工程中的Jar。

3.代码

package com.fqxyi.androidutils.test;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;

/**
 * Java方法测试类
 */
public class JavaTest {

    public static void main(String[] args) {
        try {
            modifyClass();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void modifyClass() throws Exception {
        ClassPool pool = ClassPool.getDefault();
        //设置目标类的路径
        pool.insertClassPath("C:\\Users\\Administrator\\Desktop\\hyphenatechat_3.4.2\\") ;
        //获得要修改的类
        CtClass cc =pool.get("com.hyphenate.chat.EMClient");//就是对EMClient.class的映射
        //得到方法
        CtMethod m = cc.getDeclaredMethod("loadLibrary");
        //可以在函数的开头插入新的代码
        //m.insertBefore("{return true;}") ;
        //也可以自定义loadLibrary方法的内容
        m.setBody("{if (!libraryLoaded)\n" +
                "    {\n" +
                "      _loadLibrary(\"sqlite\");\n" +
                "      _loadLibrary(\"hyphenate_av\");\n" +
                "      _loadLibrary(\"hyphenate_av_recorder\");\n" +
                "      _loadLibrary(\"hyphenate\");\n" +
                "      libraryLoaded = true;\n" +
                "    }}");
        //保存到文件里,会在项目根目录下生成一个EMClient.class,并没有自动替换EMClient.class,需要自己手动替换进去
        cc.writeFile() ;
    }

}

参考文章

更好的方式

AOP:以后总结

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,268评论 19 139
  • 对于agent,是在vm启动,执行方法前,将字节码修改的服务代理。 对于javassist,是修改字节码具体实现。...
    城市里永远的学习者阅读 5,136评论 2 55
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 174,593评论 25 709
  • 大概,农村的孩子,就酷爱村庄,反正我是。田野,荒草,乡间小道以及小道两边的树,田埂和沟壑。还有村里面的人们...
    龙青阅读 428评论 1 5
  • 当你随波逐流,无论现在多厉害,都会有一天,累到沙滩,看不见自己要去的地方!当你争名夺利,无论你多本事,都会有一天,...
    hff韩范范阅读 737评论 0 1