序
例子
最近線上報了一個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
需要下載內容
使用步驟
- 依賴javassist Jar;
- 使用
jar xvf oldJar.jar
命令解壓縮oldJar到當前目錄下; - 編寫程式碼;
- 使用
jd-gui
驗證newClass檔案是否正確; - 使用
jar cvfm META-INF\MANIFEST.MF newJar.jar *
命令將當前目錄下的所有檔案壓縮成newJar,並且使用環信生成的MANIFEST.MF; - 用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:以後總結