Skip to content

Commit

Permalink
fix: ClassLoader not working with Java 9+
Browse files Browse the repository at this point in the history
  • Loading branch information
danthe1st committed May 7, 2022
1 parent 7a6025a commit 3a11e11
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 37 deletions.
4 changes: 1 addition & 3 deletions src/main/kotlin/app/revanced/cli/MainCommand.kt
Original file line number Diff line number Diff line change
@@ -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.*
Expand Down Expand Up @@ -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)
}
}
Expand Down
4 changes: 1 addition & 3 deletions src/main/kotlin/app/revanced/cli/Patcher.kt
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -59,9 +58,8 @@ internal class Patcher {
val checkInclude = MainCommand.includedPatches.isNotEmpty()

MainCommand.patchBundles.forEach { bundle ->
PatchLoader.injectPatches(bundle)
val includedPatches = mutableListOf<Patch<Data>>()
Patches.loadPatches().forEach patch@{
Patches.load(bundle).forEach patch@{
val patch = it()

// TODO: filter out incompatible patches with package metadata
Expand Down
17 changes: 1 addition & 16 deletions src/main/kotlin/app/revanced/patch/PatchLoader.kt
Original file line number Diff line number Diff line change
@@ -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
)
}
}

}
}
31 changes: 21 additions & 10 deletions src/main/kotlin/app/revanced/patch/Patches.kt
Original file line number Diff line number Diff line change
@@ -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<Data>> {
val url = patchFile.toURI().toURL()
val classLoader = URLClassLoader(arrayOf(url))
return loadIndex(classLoader).patches
}
}
private fun loadIndex(classLoader: ClassLoader) = classLoader
.loadClass(Index::class.java.canonicalName)
.fields
.first()
.get(null) as Index
}
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion src/main/kotlin/app/revanced/utils/signing/Signer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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<String, String> = LinkedHashMap()
Expand Down

0 comments on commit 3a11e11

Please sign in to comment.