Use built-in DelegateLastClassLoader for extensions (#3874)
Assisted-by: Claude:claude-opus-5
This commit is contained in:
@@ -13,13 +13,13 @@ import eu.kanade.tachiyomi.source.Source
|
||||
import eu.kanade.tachiyomi.source.SourceFactory
|
||||
import eu.kanade.tachiyomi.util.lang.Hash
|
||||
import eu.kanade.tachiyomi.util.storage.copyAndSetReadOnlyTo
|
||||
import eu.kanade.tachiyomi.util.system.ChildFirstPathClassLoader
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import logcat.LogPriority
|
||||
import mihon.app.di.appGraph
|
||||
import mihon.data.dalvik.DelegateLastClassLoaderCompat
|
||||
import tachiyomi.core.common.util.system.logcat
|
||||
import java.io.File
|
||||
|
||||
@@ -277,7 +277,7 @@ internal object ExtensionLoader {
|
||||
}
|
||||
|
||||
val classLoader = try {
|
||||
ChildFirstPathClassLoader(appInfo.sourceDir, null, context.classLoader)
|
||||
DelegateLastClassLoaderCompat(appInfo.sourceDir, null, context.classLoader)
|
||||
} catch (e: Exception) {
|
||||
logcat(LogPriority.ERROR, e) { "Extension load error: $extName ($pkgName)" }
|
||||
return LoadResult.Error
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
package eu.kanade.tachiyomi.util.system
|
||||
|
||||
import dalvik.system.PathClassLoader
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
import java.net.URL
|
||||
import java.util.Enumeration
|
||||
|
||||
/**
|
||||
* A parent-last class loader that will try in order:
|
||||
* - the system class loader
|
||||
* - the child class loader
|
||||
* - the parent class loader.
|
||||
*/
|
||||
class ChildFirstPathClassLoader(
|
||||
dexPath: String,
|
||||
librarySearchPath: String?,
|
||||
parent: ClassLoader,
|
||||
) : PathClassLoader(dexPath, librarySearchPath, parent) {
|
||||
|
||||
private val systemClassLoader: ClassLoader? = getSystemClassLoader()
|
||||
|
||||
override fun loadClass(name: String?, resolve: Boolean): Class<*> {
|
||||
var c = findLoadedClass(name)
|
||||
|
||||
if (c == null && systemClassLoader != null) {
|
||||
try {
|
||||
c = systemClassLoader.loadClass(name)
|
||||
} catch (_: ClassNotFoundException) {}
|
||||
}
|
||||
|
||||
if (c == null) {
|
||||
c = try {
|
||||
findClass(name)
|
||||
} catch (_: ClassNotFoundException) {
|
||||
super.loadClass(name, resolve)
|
||||
}
|
||||
}
|
||||
|
||||
if (resolve) {
|
||||
resolveClass(c)
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
override fun getResource(name: String?): URL? {
|
||||
return systemClassLoader?.getResource(name)
|
||||
?: findResource(name)
|
||||
?: super.getResource(name)
|
||||
}
|
||||
|
||||
override fun getResources(name: String?): Enumeration<URL> {
|
||||
val systemUrls = systemClassLoader?.getResources(name)
|
||||
val localUrls = findResources(name)
|
||||
val parentUrls = parent?.getResources(name)
|
||||
val urls = buildList {
|
||||
while (systemUrls?.hasMoreElements() == true) {
|
||||
add(systemUrls.nextElement())
|
||||
}
|
||||
|
||||
while (localUrls?.hasMoreElements() == true) {
|
||||
add(localUrls.nextElement())
|
||||
}
|
||||
|
||||
while (parentUrls?.hasMoreElements() == true) {
|
||||
add(parentUrls.nextElement())
|
||||
}
|
||||
}
|
||||
|
||||
return object : Enumeration<URL> {
|
||||
val iterator = urls.iterator()
|
||||
|
||||
override fun hasMoreElements() = iterator.hasNext()
|
||||
override fun nextElement() = iterator.next()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getResourceAsStream(name: String?): InputStream? {
|
||||
return try {
|
||||
getResource(name)?.openStream()
|
||||
} catch (_: IOException) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user