Skip to content

Commit

Permalink
Add missing files
Browse files Browse the repository at this point in the history
Signed-off-by: Francisco Solis <imfran@duck.com>
  • Loading branch information
Im-Fran committed Apr 13, 2023
1 parent e677c05 commit 99fbb5e
Showing 1 changed file with 105 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package xyz.theprogramsrc.simplecoreapi.global.module

import com.google.common.io.ByteStreams
import java.io.File
import java.net.URLClassLoader
import java.security.CodeSource
import java.util.concurrent.CopyOnWriteArraySet
import java.util.jar.JarFile

class ModuleClassLoader(
private val moduleDescription: ModuleDescription,
private val file: File
): URLClassLoader(arrayOf(file.toURI().toURL())) {

companion object {
private val loaders = CopyOnWriteArraySet<ModuleClassLoader>()

init {
ClassLoader.registerAsParallelCapable()
}
}

private val jarFile = JarFile(file)
private val url = file.toURI().toURL()
private val manifest = jarFile.manifest
private var module: Module? = null

init {
loaders.add(this)
}

override fun loadClass(name: String, resolve: Boolean): Class<*> = loadClassInternally(name, resolve)

private fun loadClassInternally(name: String, resolve: Boolean, checkOther: Boolean = true): Class<*> {
try {
val result = super.loadClass(name, resolve)
if(checkOther || result.classLoader == this) {
return result
}
} catch (_: ClassNotFoundException) {}

if (checkOther) {
for (loader in loaders) {
if (loader != this) {
try {
return loader.loadClassInternally(name, resolve, false)
} catch (_: ClassNotFoundException) {}
}
}
}

throw ClassNotFoundException(name)
}

override fun findClass(name: String): Class<*> {
val path = name.replace('.', '/').plus(".class")
val entry = jarFile.getJarEntry(path)

val classBytes = jarFile.getInputStream(entry).use {
ByteStreams.toByteArray(it)
}

val dot = name.lastIndexOf('.')
if(dot != -1) {
val pkgName = name.substring(0, dot)
if(getPackage(pkgName) == null) {
try {
if(manifest != null) {
definePackage(pkgName, manifest, url)
} else {
definePackage(pkgName, null, null, null, null, null, null, null)
}
}catch (_: IllegalArgumentException) {
if(getPackage(pkgName) == null) {
throw IllegalStateException("Cannot find package $pkgName")
}
}
}

val signers = entry.codeSigners
return defineClass(name, classBytes, 0, classBytes.size, CodeSource(url, signers))
}

return super.findClass(name)
}

override fun close() {
jarFile.use {
super.close()
}
}

fun init(module: Module) {
check(module.javaClass.classLoader == this) {
"Module class loader mismatch"
}

check(this.module == null) {
"Module already initialized"
}

this.module = module
module.init(this.file, this.moduleDescription)
}
}

0 comments on commit 99fbb5e

Please sign in to comment.