Skip to content

Commit

Permalink
[core] Support loading service from classloaders other than current (#…
Browse files Browse the repository at this point in the history
…2428)

* fix: load service, close #2268 #2427

* fix: check empty
  • Loading branch information
cssxsh committed Feb 17, 2023
1 parent e686a23 commit 9f36eff
Showing 1 changed file with 10 additions and 1 deletion.
11 changes: 10 additions & 1 deletion mirai-core-utils/src/jvmBaseMain/kotlin/Services.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import kotlin.reflect.full.createInstance
public actual fun <T : Any> loadService(clazz: KClass<out T>, fallbackImplementation: String?): T {
var suppressed: Throwable? = null
return ServiceLoader.load(clazz.java).firstOrNull()
?: ServiceLoader.load(clazz.java, clazz.java.classLoader).firstOrNull()
?: (if (fallbackImplementation == null) null
else runCatching { findCreateInstance<T>(fallbackImplementation) }.onFailure { suppressed = it }.getOrNull())
?: throw NoSuchElementException("Could not find an implementation for service class ${clazz.qualifiedName}").apply {
Expand All @@ -29,10 +30,18 @@ private fun <T : Any> findCreateInstance(fallbackImplementation: String): T {

public actual fun <T : Any> loadServiceOrNull(clazz: KClass<out T>, fallbackImplementation: String?): T? {
return ServiceLoader.load(clazz.java).firstOrNull()
?: ServiceLoader.load(clazz.java, clazz.java.classLoader).firstOrNull()
?: if (fallbackImplementation == null) return null
else runCatching { findCreateInstance<T>(fallbackImplementation) }.getOrNull()
}

public actual fun <T : Any> loadServices(clazz: KClass<out T>): Sequence<T> {
return ServiceLoader.load(clazz.java).asSequence()
return sequence {
val current = ServiceLoader.load(clazz.java).iterator()
if (current.hasNext()) {
yieldAll(current)
} else {
yieldAll(ServiceLoader.load(clazz.java, clazz.java.classLoader))
}
}
}

0 comments on commit 9f36eff

Please sign in to comment.