修改Jar內容

風清袖一發表於2018-11-05

例子

最近線上報了一個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:以後總結

相關文章