@@ -82,6 +82,26 @@ internal class DynLibClassLoader(
82
82
clName?.let { return " DynLibClassLoader{$it }" }
83
83
return " DynLibClassLoader@" + hashCode()
84
84
}
85
+
86
+ override fun getResource (name : String? ): URL ? {
87
+ if (name == null ) return null
88
+ findResource(name)?.let { return it }
89
+ if (parent is DynLibClassLoader ) {
90
+ return parent.getResource(name)
91
+ }
92
+ return null
93
+ }
94
+
95
+ override fun getResources (name : String? ): Enumeration <URL > {
96
+ if (name == null ) return Collections .emptyEnumeration()
97
+ val res = findResources(name)
98
+ return if (parent is DynLibClassLoader ) {
99
+ res + parent.getResources(name)
100
+ } else {
101
+ res
102
+ }
103
+ }
104
+
85
105
}
86
106
87
107
@Suppress(" JoinDeclarationAndAssignment" )
@@ -210,7 +230,8 @@ internal class JvmPluginClassLoaderN : URLClassLoader {
210
230
findLoadedClass(name)?.let { return it }
211
231
try {
212
232
return super .findClass(name)
213
- } catch (ignored: ClassNotFoundException ) {}
233
+ } catch (ignored: ClassNotFoundException ) {
234
+ }
214
235
}
215
236
}
216
237
return null
@@ -265,11 +286,48 @@ internal class JvmPluginClassLoaderN : URLClassLoader {
265
286
266
287
internal fun loadedClass (name : String ): Class <* >? = super .findLoadedClass(name)
267
288
268
- // // 只允许插件 getResource 时获取插件自身资源, https://github.com/mamoe/mirai-console/issues/205
269
- override fun getResources (name : String? ): Enumeration <URL > = findResources(name)
270
- override fun getResource (name : String? ): URL ? = findResource(name)
271
- // getResourceAsStream 在 URLClassLoader 中通过 getResource 确定资源
272
- // 因此无需 override getResourceAsStream
289
+ private fun getRes (name : String , shared : Boolean ): Enumeration <URL > {
290
+ val src = mutableListOf<Enumeration <URL >>(
291
+ findResources(name),
292
+ )
293
+ if (dependencies.isEmpty()) {
294
+ if (shared) {
295
+ src.add(sharedLibrariesLogger.getResources(name))
296
+ }
297
+ } else {
298
+ dependencies.forEach { dep ->
299
+ src.add(dep.getRes(name, false ))
300
+ }
301
+ }
302
+ src.add(pluginIndependentCL.getResources(name))
303
+
304
+ val resolved = mutableSetOf<URL >()
305
+ src.forEach { nested -> nested.iterator().forEach { resolved.add(it) } }
306
+
307
+ return Collections .enumeration(resolved)
308
+ }
309
+
310
+ override fun getResources (name : String? ): Enumeration <URL > {
311
+ name ? : return Collections .emptyEnumeration()
312
+
313
+ if (name.startsWith(" META-INF/mirai-console-plugin/" ))
314
+ return findResources(name)
315
+
316
+ return getRes(name, true )
317
+ }
318
+
319
+ override fun getResource (name : String? ): URL ? {
320
+ name ? : return null
321
+ if (name.startsWith(" META-INF/mirai-console-plugin/" ))
322
+ return findResource(name)
323
+ findResource(name)?.let { return it }
324
+ // parent: ctx.sharedLibrariesLoader
325
+ sharedLibrariesLogger.getResource(name)?.let { return it }
326
+ dependencies.forEach { dep ->
327
+ dep.getResource(name)?.let { return it }
328
+ }
329
+ return pluginIndependentCL.getResource(name)
330
+ }
273
331
274
332
override fun toString (): String {
275
333
return " JvmPluginClassLoader{${file.name} }"
@@ -278,3 +336,35 @@ internal class JvmPluginClassLoaderN : URLClassLoader {
278
336
279
337
private fun String.pkgName (): String = substringBeforeLast(' .' , " " )
280
338
internal fun Artifact.depId (): String = " $groupId :$artifactId "
339
+
340
+ private operator fun <E > Enumeration<E>.plus (next : Enumeration <E >): Enumeration <E > {
341
+ return compoundEnumerations(listOf (this , next).iterator())
342
+ }
343
+
344
+ private fun <E > compoundEnumerations (iter : Iterator <Enumeration <E >>): Enumeration <E > {
345
+ return object : Enumeration <E > {
346
+ private lateinit var crt: Enumeration <E >
347
+ override fun hasMoreElements (): Boolean {
348
+ return (::crt.isInitialized && crt.hasMoreElements()) || iter.hasNext()
349
+ }
350
+
351
+ override fun nextElement (): E {
352
+ if (::crt.isInitialized) {
353
+ val c = crt
354
+ return if (c.hasMoreElements()) {
355
+ c.nextElement()
356
+ } else if (iter.hasNext()) {
357
+ crt = iter.next()
358
+ nextElement()
359
+ } else {
360
+ throw NoSuchElementException ()
361
+ }
362
+ } else if (iter.hasNext()) {
363
+ crt = iter.next()
364
+ return nextElement()
365
+ } else {
366
+ throw NoSuchElementException ()
367
+ }
368
+ }
369
+ }
370
+ }
0 commit comments