From 3a11e1135bd1e8958dd21247622d549440725ead Mon Sep 17 00:00:00 2001 From: danthe1st Date: Sat, 7 May 2022 21:05:09 +0200 Subject: [PATCH] fix: ClassLoader not working with Java 9+ --- .../kotlin/app/revanced/cli/MainCommand.kt | 4 +-- src/main/kotlin/app/revanced/cli/Patcher.kt | 4 +-- .../kotlin/app/revanced/patch/PatchLoader.kt | 17 +--------- src/main/kotlin/app/revanced/patch/Patches.kt | 31 +++++++++++++------ .../utils/filesystem/FileSystemUtils.kt | 5 +-- .../app/revanced/utils/signing/Signer.kt | 2 +- 6 files changed, 26 insertions(+), 37 deletions(-) diff --git a/src/main/kotlin/app/revanced/cli/MainCommand.kt b/src/main/kotlin/app/revanced/cli/MainCommand.kt index 29afa52..0bed6d2 100644 --- a/src/main/kotlin/app/revanced/cli/MainCommand.kt +++ b/src/main/kotlin/app/revanced/cli/MainCommand.kt @@ -1,6 +1,5 @@ package app.revanced.cli -import app.revanced.patch.PatchLoader import app.revanced.patch.Patches import app.revanced.utils.adb.Adb import picocli.CommandLine.* @@ -49,8 +48,7 @@ internal object MainCommand : Runnable { override fun run() { if (listOnly) { patchBundles.forEach { - PatchLoader.injectPatches(it) - Patches.loadPatches().forEach { + Patches.load(it).forEach { println(it().metadata) } } diff --git a/src/main/kotlin/app/revanced/cli/Patcher.kt b/src/main/kotlin/app/revanced/cli/Patcher.kt index 59a6b78..e0f1d7f 100644 --- a/src/main/kotlin/app/revanced/cli/Patcher.kt +++ b/src/main/kotlin/app/revanced/cli/Patcher.kt @@ -1,6 +1,5 @@ package app.revanced.cli -import app.revanced.patch.PatchLoader import app.revanced.patch.Patches import app.revanced.patcher.data.base.Data import app.revanced.patcher.patch.base.Patch @@ -59,9 +58,8 @@ internal class Patcher { val checkInclude = MainCommand.includedPatches.isNotEmpty() MainCommand.patchBundles.forEach { bundle -> - PatchLoader.injectPatches(bundle) val includedPatches = mutableListOf>() - Patches.loadPatches().forEach patch@{ + Patches.load(bundle).forEach patch@{ val patch = it() // TODO: filter out incompatible patches with package metadata diff --git a/src/main/kotlin/app/revanced/patch/PatchLoader.kt b/src/main/kotlin/app/revanced/patch/PatchLoader.kt index 74ca2fd..088076f 100644 --- a/src/main/kotlin/app/revanced/patch/PatchLoader.kt +++ b/src/main/kotlin/app/revanced/patch/PatchLoader.kt @@ -1,25 +1,10 @@ package app.revanced.patch import java.io.File -import java.net.URL import java.net.URLClassLoader internal class PatchLoader { internal companion object { - internal fun injectPatches(file: File) { - // This function will fail on Java 9 and above. - try { - val url = file.toURI().toURL() - val classLoader = Thread.currentThread().contextClassLoader as URLClassLoader - val method = URLClassLoader::class.java.getDeclaredMethod("addURL", URL::class.java) - method.isAccessible = true - method.invoke(classLoader, url) - } catch (e: Exception) { - throw Exception( - "Failed to inject patches! The CLI does NOT work on Java 9 and above, please use Java 8!", - e // propagate exception - ) - } - } + } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patch/Patches.kt b/src/main/kotlin/app/revanced/patch/Patches.kt index 7ba8147..b302c90 100644 --- a/src/main/kotlin/app/revanced/patch/Patches.kt +++ b/src/main/kotlin/app/revanced/patch/Patches.kt @@ -1,15 +1,26 @@ package app.revanced.patch +import app.revanced.patcher.data.base.Data +import app.revanced.patcher.patch.base.Patch import app.revanced.patches.Index +import java.io.File +import java.net.URLClassLoader -internal class Patches { - internal companion object { - // You may ask yourself, "why do this?". - // We do it like this, because we don't want the Index class - // to be loaded while the dependency hasn't been injected yet. - // You can see this as "controlled class loading". - // Whenever this class is loaded (because it is invoked), all the imports - // will be loaded too. We don't want to do this until we've injected the class. - internal fun loadPatches() = Index.patches +internal object Patches { + + + /** + * This method loads patches from a given patch file + * @return the loaded patches represented as a list of functions returning instances of [Patch] + */ + internal fun load(patchFile: File): List<() -> Patch> { + val url = patchFile.toURI().toURL() + val classLoader = URLClassLoader(arrayOf(url)) + return loadIndex(classLoader).patches } -} \ No newline at end of file + private fun loadIndex(classLoader: ClassLoader) = classLoader + .loadClass(Index::class.java.canonicalName) + .fields + .first() + .get(null) as Index +} diff --git a/src/main/kotlin/app/revanced/utils/filesystem/FileSystemUtils.kt b/src/main/kotlin/app/revanced/utils/filesystem/FileSystemUtils.kt index 10559d8..7a1d32e 100644 --- a/src/main/kotlin/app/revanced/utils/filesystem/FileSystemUtils.kt +++ b/src/main/kotlin/app/revanced/utils/filesystem/FileSystemUtils.kt @@ -12,10 +12,7 @@ internal class FileSystemUtils( private var fileSystem: FileSystem init { - fileSystem = FileSystems.newFileSystem( - file.toPath(), - null - ) + fileSystem = FileSystems.newFileSystem(file.toPath(), null as ClassLoader?) } private fun deleteDirectory(dirPath: String) { diff --git a/src/main/kotlin/app/revanced/utils/signing/Signer.kt b/src/main/kotlin/app/revanced/utils/signing/Signer.kt index ff56a29..16adfe4 100644 --- a/src/main/kotlin/app/revanced/utils/signing/Signer.kt +++ b/src/main/kotlin/app/revanced/utils/signing/Signer.kt @@ -91,7 +91,7 @@ object Signer { (keyStore.getKey(alias, PASSWORD) as PrivateKey) ) - val zip = FileSystems.newFileSystem(apkFile.toPath(), null) + val zip = FileSystems.newFileSystem(apkFile.toPath(), null as ClassLoader?) val dig = MessageDigest.getInstance("SHA1") val digests: MutableMap = LinkedHashMap()