当前位置: 首页 > news >正文

Framework.jar里的类无法通过Class.forName反射某个类的问题排查

1,背景

我们想要在system_server进程里扩展一些我们自己的功能。

考虑到解耦和编译依赖的问题,我们用PRODUCT_SYSTEM_SERVER_JARS预置我们的类,然后用反射jar里面的类的方式来实现代码引用。

2,遇到的问题

在SystemServer.java里用Class.forName可以反射到目标类。
在ParsingPackageUtils.java里用Class.forName 无法 反射到目标类。

log如下:
04-24 14:58:43.514 811 811 W PackageParsing: initSystemServerJarDemo, got exception.
04-24 14:58:43.514 811 811 W PackageParsing: at com.android.internal.pm.pkg.parsing.ParsingPackageUtils.initSystemServerJarDemo(ParsingPackageUtils.java:329)
04-24 14:58:46.120 811 811 D SystemServer: initSystemServerJarDemo, result:2

两个java里反射时,使用的是一样的方法:

    private void initSystemServerJarDemo(){String classPath = "com.demo.systemserverdemo.SystemServerDemo";try {Class classObj = Class.forName(classPath);Object obj = classObj.getDeclaredConstructor().newInstance();Method method = obj.getClass().getDeclaredMethod("test");method.setAccessible(true);int result = (int) method.invoke(obj);Slog.d(TAG, "initSystemServerJarDemo, result:"+result);} catch (Throwable ex){Slog.d(TAG, "initSystemServerJarDemo, got exception.", ex);}}

3, 问题分析

3.1,原因猜测

可能是类加载器的双亲委派机制导致的。

ParsingPackageUtils.java在framework.jar里;SystemServer.java在service.jar里。
framework.jar属于bootJar,加载顺序在service.jar之前;
framework.jar的类加载器,有可能是services.jar的父加载器。

类加载器会向当前ClassLoader和父加载器ClassLoader查找目标class;
framework.jar里的ParsingPackageUtils.java不会向子加载器查询SYSTEM_SERVER_JARS里的类;

3.2,验证结论

我们可以打印出来SystemServer.java的ClassLoader及其父加载器。
并打印出来ParsingPackageUtils.java的ClassLoader及其父加载器。
来确认类加载器对象是否存在父子关系。
使用以下方法打印类加载器信息:
private void printClassLoader(){
boolean recycle = true;
ClassLoader loader = getClass().getClassLoader();
while (recycle){
if(loader == null){
recycle = false;
return;
}
Slog.d(TAG, “initSystemServerJarDemo, loader hash:”+loader.hashCode()+“, loader class:”+loader.getClass().getName());
loader = loader.getParent();
}
}
输出如下:
04-24 15:21:27.443 806 806 D PackageParsing: initSystemServerJarDemo, loader hash:3047529, loader class:java.lang.BootClassLoader
04-24 15:21:30.883 806 806 D SystemServer: initSystemServerJarDemo, loader hash:179379372, loader class:dalvik.system.PathClassLoader
04-24 15:21:30.884 806 806 D SystemServer: initSystemServerJarDemo, loader hash:3047529, loader class:java.lang.BootClassLoader

3.3 结论

把类加载器打印出来,发现framework-PackageParsing的ClassLoader hash:3047529,
确实是SystemServer的类加载器(hash:179379372)的父类。

所以父加载器(hash:3047529)里的类,无法拿到子加载器里的东西。

因为Class.forName就是拿当前类加载器去查找类的。

libcore/ojluni/src/main/java/java/lang/Class.java

    public static Class<?> forName(String className)throws ClassNotFoundException {Class<?> caller = Reflection.getCallerClass();//当前类return forName(className, true, ClassLoader.getClassLoader(caller));}

4,改善

我们无法在framework.jar里的java类里,通过当前类加载器拿到目标类。
我们可以创建一个新的类加载器,就可以加载jar里面的类。

DexClassLoader classLoader = new DexClassLoader("/system/framework/**Demo.jar",null, null,this.class.getClassLoader());
Class classObj = classLoader.loadClass("com.demo.systemserverdemo.SystemServerDemo");
Constructor constructor = classObj.getDeclaredConstructor();
constructor.setAccessible(true);
constructor.newInstance();

--------------------------------end-----------------------------------

http://www.xdnf.cn/news/112123.html

相关文章:

  • FPGA上实现YOLOv5的一般过程
  • 机器学习特征工程中的数值分箱技术:原理、方法与实例解析
  • 看一看 中间件Middleware
  • mapbox高阶,高程影像、行政区边界阴影效果实现
  • 开源项目实战学习之YOLO11:ultralytics-cfg-datasets-lvis.yaml文件(五)
  • 长城杯铁人三项初赛-REVERSE复现
  • Linux常见指令介绍下(入门级)
  • 手搓雷达图(MATLAB)
  • Java24新增特性
  • C语言数据结构之顺序表
  • 从代码学习深度学习 - 图像增广 PyTorch 版
  • 解决VSCode每次SSH连接服务器时,都需要下载vscode-server
  • Rust 2025:内存安全革命与异步编程新纪元
  • 大模型技术全景解析:从基础架构到Prompt工程
  • 无感字符编码原址转换术——系统内存(Mermaid文本图表版/DeepSeek)
  • 7.9 Python+Click实战:5步打造高效的GitHub监控CLI工具
  • #define STEUER_A_H {PWM_A_ON}
  • CSS3 基础(背景-文本效果)
  • 04-stm32的标准外设库
  • TI MSP430搭配 SD NAND(贴片式T卡):长续航心电监测的可靠保障
  • 关于按键映射软件的探索(其一)
  • STM32F407使用ESP8266实现阿里云OTA(下)
  • postgis:添加索引时提示“对访问方法 gist 数据类型 geometry 没有默认的操作符表“
  • 将视频生成视频二维码步骤
  • 深入浅出学会函数(下)
  • 【霍夫变换】图像处理(OpenCV)-part11
  • 【阿里云大模型高级工程师ACP习题集】2.4 自动化评测答疑机器人的表现(⭐️⭐️⭐️ 重点章节!!!)
  • 数据结构-图
  • HOW - Code Review 流程自动化
  • 学习threejs,使用EffectComposer后期处理组合器(采用RenderPass、ShaderPass渲染通道),案例一