We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
我排查后发现 issue#999 是相同问题
错误信息如下: java.util.concurrent.ExecutionException: java.util.concurrent.ExecutionException: java.util.concurrent.ExecutionException: java.lang.ClassCastException: Cannot cast androidx.core.app.CoreComponentFactory to com.tencent.shadow.core.runtime.ShadowAppComponentFactory
问题发生在LoadPluginBloc#loadPlugin方法中,通过pluginClassLoader加载androidx.core.app.CoreComponentFactory时,加载出来的clazz对应的classLoader不正确,不是PluginClassLoader,导致后续的强制类型转换失败。
问题分析: 1.正常情况下,宿主的ClassLoader链如下: PatchClassLoader(当前宿主classLoader)->BootClassLoader
2.Tinker在加载dex时会使用DelegateClassLoader,导致宿主ClassLoader链变为: DelegateClassLoader(当前宿主classLoader)->PathClassLoader->BootClassLoader
3.使用Shadow框架后,插件使用的ClassLoader链为: PluginClassLoader->DelegateClassLoader(当前宿主classLoader)->PathClassLoader->BootClassLoader
4.同时PluginClassLoader还会持有specialClassLoader(即宿主classLoader的parent) 非tinker下,specialClassLoader为BootClassLoader tinker下,specialClassLoader为PathClassLoader
5.PluginClassLoader.loadClass逻辑会优先从其specialclassLoader加载 非tinker情况下,因为BootClassLoader没有AndroidX的类,最终会走PluginClassLoader自己的加载逻辑,加载插件中的AppComponentFactory Tinker情况下,PathClassLoader可以加载到AndroidX的类,所以直接加载了宿主的AppCompoentFactory,导致后续强转失败。
实际上,不一定是tinker,只要宿主存在修改宿主ClassLoader的行为,都会出现上述一样的问题
疑问: 问题的关键在于specialclassLoader,对于这个变量,我没有太理解它的真实定义: 1.它代表的是BootClassLoader,即宿主classLoader的最高祖先 2.它代表的是宿主的parent,那这个变量的实际内容在不同情况下会不同
如果是上述1的情况,应该可以在PluginClassLoader构造时,优化一下specialclassLoader的计算逻辑,就可兼容宿主ClassLoader链被修改的问题。 如果是上述2的情况,想了解下这么设计的作用,我目前没有太看懂PluginClassLoader#loadClass这个方法的内容
The text was updated successfully, but these errors were encountered:
插件依赖宿主中打包的一些shadow的类和白名单允许复用的类,这些类需要通过parent加载。其余的类插件和宿主是要隔离开的,所以要跳过parent,从special加载。
这个special也不能固定成Bootclassloader,因为多个插件可能还有依赖关系。还有runtime动态化的classloader也是宿主的parent。
如果shadow要和tinker兼容,显然就是取宿主parent时,再多跳过一级就行了。或者再动态的查找一下最后一个找不到宿主类的classloader。
这种兼容只能由使用者自行定制修改。shadow这种公用的代码,不适合兼容其他也修改classloader的SDK。
Sorry, something went wrong.
No branches or pull requests
我排查后发现 issue#999 是相同问题
错误信息如下:
java.util.concurrent.ExecutionException: java.util.concurrent.ExecutionException: java.util.concurrent.ExecutionException: java.lang.ClassCastException: Cannot cast androidx.core.app.CoreComponentFactory to com.tencent.shadow.core.runtime.ShadowAppComponentFactory
问题发生在LoadPluginBloc#loadPlugin方法中,通过pluginClassLoader加载androidx.core.app.CoreComponentFactory时,加载出来的clazz对应的classLoader不正确,不是PluginClassLoader,导致后续的强制类型转换失败。
![Image](https://private-user-images.githubusercontent.com/25196269/411960863-134db614-8714-4095-9351-39731bc952c1.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk1MzMyMDMsIm5iZiI6MTczOTUzMjkwMywicGF0aCI6Ii8yNTE5NjI2OS80MTE5NjA4NjMtMTM0ZGI2MTQtODcxNC00MDk1LTkzNTEtMzk3MzFiYzk1MmMxLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTQlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjE0VDExMzUwM1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTljYjM0M2ZiZGM5OWI5OWRlMTliMTYzM2Y3YWNkZTYxNWNhZmM5N2E0MjFkMDdkYzI1MGFiMzM4ZjBmYjU3NGYmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.tYwAh0Rj9A9q-KyPZhVoHkBOMlHxSNb-3DLahNgOJfM)
问题分析:
1.正常情况下,宿主的ClassLoader链如下:
PatchClassLoader(当前宿主classLoader)->BootClassLoader
2.Tinker在加载dex时会使用DelegateClassLoader,导致宿主ClassLoader链变为:
DelegateClassLoader(当前宿主classLoader)->PathClassLoader->BootClassLoader
3.使用Shadow框架后,插件使用的ClassLoader链为:
PluginClassLoader->DelegateClassLoader(当前宿主classLoader)->PathClassLoader->BootClassLoader
4.同时PluginClassLoader还会持有specialClassLoader(即宿主classLoader的parent)
非tinker下,specialClassLoader为BootClassLoader
tinker下,specialClassLoader为PathClassLoader
5.PluginClassLoader.loadClass逻辑会优先从其specialclassLoader加载
![Image](https://private-user-images.githubusercontent.com/25196269/411965052-6e00f403-685f-4b3a-9ca5-a9fdeb056d26.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk1MzMyMDMsIm5iZiI6MTczOTUzMjkwMywicGF0aCI6Ii8yNTE5NjI2OS80MTE5NjUwNTItNmUwMGY0MDMtNjg1Zi00YjNhLTljYTUtYTlmZGViMDU2ZDI2LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTQlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjE0VDExMzUwM1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTlkYjE2MjczNjk4OGY2ODA2YWQ0OTQxZDBlYjdjMjRhMTMyNTQwMTI4YjM1ZWM5ZjM3OWRmM2E0MjBmNjRjMGUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.EPEDC6u0JjeZS9ZeKDTGggT_RZUowcZqoOm5YMtz7Gk)
![Image](https://private-user-images.githubusercontent.com/25196269/411966181-3ead66b1-9a61-4e60-9f3a-9da744f4a2a6.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzk1MzMyMDMsIm5iZiI6MTczOTUzMjkwMywicGF0aCI6Ii8yNTE5NjI2OS80MTE5NjYxODEtM2VhZDY2YjEtOWE2MS00ZTYwLTlmM2EtOWRhNzQ0ZjRhMmE2LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTQlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjE0VDExMzUwM1omWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTMzZWIyNjA4NGFjYzkyYjE2ZjYxM2Q4MTg5YTY1YWM3YzAwMGJjNWRlNzVlY2RhMzRlMmUwMWJhNTY1ZjU0YmImWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.KlCjaViXgESTKIoG1s6UYFWjKb3-dxDQ6t0lku87950)
非tinker情况下,因为BootClassLoader没有AndroidX的类,最终会走PluginClassLoader自己的加载逻辑,加载插件中的AppComponentFactory
Tinker情况下,PathClassLoader可以加载到AndroidX的类,所以直接加载了宿主的AppCompoentFactory,导致后续强转失败。
实际上,不一定是tinker,只要宿主存在修改宿主ClassLoader的行为,都会出现上述一样的问题
疑问:
问题的关键在于specialclassLoader,对于这个变量,我没有太理解它的真实定义:
1.它代表的是BootClassLoader,即宿主classLoader的最高祖先
2.它代表的是宿主的parent,那这个变量的实际内容在不同情况下会不同
如果是上述1的情况,应该可以在PluginClassLoader构造时,优化一下specialclassLoader的计算逻辑,就可兼容宿主ClassLoader链被修改的问题。
如果是上述2的情况,想了解下这么设计的作用,我目前没有太看懂PluginClassLoader#loadClass这个方法的内容
The text was updated successfully, but these errors were encountered: