From b765cac0d2852c7124d2b873189acc8d44b52629 Mon Sep 17 00:00:00 2001 From: twisti-dev <76837088+twisti-dev@users.noreply.github.com> Date: Sat, 20 Jun 2026 15:17:56 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A7=20chore:=20update=20version=20to?= =?UTF-8?q?=203.27.0=20and=20improve=20service=20loading=20compatibility?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - increment version in gradle.properties from 3.26.0 to 3.27.0 - refactor requiredService function to use ServiceUtil for better fallback handling - add ServiceUtil object to manage service loading with fallback logic - ensure backward compatibility with Adventure 4 in SurfComponentBuilderImpl --- gradle.properties | 2 +- .../surf-api-core/api/surf-api-core.api | 5 +++ .../builder/SurfComponentBuilderImpl.kt | 5 ++- .../slne/surf/api/core/util/service-util.kt | 37 ++++++++++++++++++- 4 files changed, 45 insertions(+), 4 deletions(-) diff --git a/gradle.properties b/gradle.properties index 1ad722fc..1fefb951 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,6 +7,6 @@ org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled javaVersion=25 mcVersion=26.2 group=dev.slne.surf.api -version=3.26.0 +version=3.27.0 relocationPrefix=dev.slne.surf.api.libs snapshot=false diff --git a/surf-api-core/surf-api-core/api/surf-api-core.api b/surf-api-core/surf-api-core/api/surf-api-core.api index f1aa3389..a30bf824 100644 --- a/surf-api-core/surf-api-core/api/surf-api-core.api +++ b/surf-api-core/surf-api-core/api/surf-api-core.api @@ -11057,6 +11057,11 @@ public final class dev/slne/surf/api/core/util/SerializableErrorKt { public static final fun toSerializableError (Ljava/lang/Throwable;)Ldev/slne/surf/api/core/util/SerializableError; } +public final class dev/slne/surf/api/core/util/ServiceUtil { + public static final field INSTANCE Ldev/slne/surf/api/core/util/ServiceUtil; + public final fun serviceWithFallback (Ljava/util/ServiceLoader;Ljava/lang/Class;)Ljava/lang/Object; +} + public abstract class dev/slne/surf/api/core/util/SurfTypeParameterMatcher { public static final field Companion Ldev/slne/surf/api/core/util/SurfTypeParameterMatcher$Companion; public fun ()V diff --git a/surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/messages/builder/SurfComponentBuilderImpl.kt b/surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/messages/builder/SurfComponentBuilderImpl.kt index f49c5206..48523ef1 100644 --- a/surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/messages/builder/SurfComponentBuilderImpl.kt +++ b/surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/messages/builder/SurfComponentBuilderImpl.kt @@ -21,7 +21,10 @@ internal class SurfComponentBuilderImpl(private val delegate: TextComponent.Buil override fun content(content: String) = withDelegate { content(content) } override fun content() = delegate.content() override fun children(): List = delegate.children() - override fun build() = delegate.build() + override fun build(): TextComponent { + // Adventure 4 backward compatibility. #build() would return BuildableComponent instead of TextComponent in adventure 4 + return delegate.asComponent() as TextComponent + } override fun append(builder: ComponentBuilder<*, *>) = withDelegate { append(builder) } override fun append(component: Component) = withDelegate { append(component) } diff --git a/surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/util/service-util.kt b/surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/util/service-util.kt index f47da559..aad80fd2 100644 --- a/surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/util/service-util.kt +++ b/surf-api-core/surf-api-core/src/main/kotlin/dev/slne/surf/api/core/util/service-util.kt @@ -1,5 +1,6 @@ package dev.slne.surf.api.core.util +import net.kyori.adventure.internal.properties.AdventureProperties import net.kyori.adventure.util.Services import java.util.* @@ -12,9 +13,41 @@ import java.util.* * @return the service instance of type [T] * @throws ServiceConfigurationError if the service of type [T] is not available */ -inline fun requiredService(): T = Services.serviceWithFallback( +inline fun requiredService(): T = ServiceUtil.serviceWithFallback( ServiceLoader.load( T::class.java, getCallerClass()?.classLoader ?: T::class.java.classLoader ), T::class.java -).orElseThrow { ServiceConfigurationError("Service ${T::class.java.name} not available") } \ No newline at end of file +) ?: throw ServiceConfigurationError("Service ${T::class.java.name} not available") + +object ServiceUtil { + @Suppress("UnstableApiUsage") + private val SERVICE_LOAD_FAILURES_ARE_FATAL = AdventureProperties.SERVICE_LOAD_FAILURES_ARE_FATAL.value() == true + + @PublishedApi + internal fun serviceWithFallback(loader: ServiceLoader, type: Class): T? { + val iterator = loader.iterator() + var firstFallback: T? = null + + while (iterator.hasNext()) { + try { + val next = iterator.next() + if (next is Services.Fallback) { + if (firstFallback == null) { + firstFallback = next + } + } else { + return next + } + } catch (t: Throwable) { + if (SERVICE_LOAD_FAILURES_ARE_FATAL) { + throw ServiceConfigurationError("Failed to load service $type", t) + } else { + continue + } + } + } + + return firstFallback + } +} \ No newline at end of file