From e7b3c667144ad573c97ed526f5b5bd847e53f9c4 Mon Sep 17 00:00:00 2001 From: "minekube-ai-engineer[bot]" Date: Thu, 3 Sep 2026 19:36:41 +0000 Subject: [PATCH] fix(config): use SnakeYAML default ctor (2.x compatible) for existing-config load --- core/build.gradle.kts | 7 +++-- .../minekube/connect/config/ConfigLoader.java | 5 ++-- .../connect/config/ConfigLoaderTest.java | 27 +++++++++++++++++++ 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 894ea3f4d..788582ab0 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -33,8 +33,11 @@ dependencies { testImplementation("io.netty", "netty-transport", Versions.nettyVersion) testImplementation("io.netty", "netty-codec", Versions.nettyVersion) testImplementation("com.squareup.okhttp3:mockwebserver:4.9.3") - // Parses the release workflows in the release verification tests. - testImplementation("org.yaml:snakeyaml:1.27") + // Parses the release workflows in the release verification tests. 2.x on purpose: Velocity + // 4.x supplies SnakeYAML 2.x at runtime (via Configurate), where the no-arg SafeConstructor + // constructor no longer exists - ConfigLoaderTest's regression guard for the 0.15.10 + // NoSuchMethodError must run against the 2.x API the platform actually provides. + testImplementation("org.yaml:snakeyaml:2.2") testRuntimeOnly("org.junit.platform:junit-platform-launcher") } diff --git a/core/src/main/java/com/minekube/connect/config/ConfigLoader.java b/core/src/main/java/com/minekube/connect/config/ConfigLoader.java index d62d7e510..c4bd72f6f 100644 --- a/core/src/main/java/com/minekube/connect/config/ConfigLoader.java +++ b/core/src/main/java/com/minekube/connect/config/ConfigLoader.java @@ -51,7 +51,6 @@ import org.geysermc.configutils.file.template.ResourceTemplateReader; import org.geysermc.configutils.updater.change.Changes; import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.constructor.SafeConstructor; @Getter @RequiredArgsConstructor @@ -71,7 +70,9 @@ private static void fixPlaceholderIssue(Path path) throws IOException { private static boolean hasBedrockIdentitySection(Path path) throws IOException { try (Reader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) { - Object document = new Yaml(new SafeConstructor()).load(reader); + // Default ctor: delegates to SafeConstructor in both SnakeYAML 1.x and 2.x (the + // no-arg SafeConstructor ctor was removed in 2.0, which Velocity provides at runtime). + Object document = new Yaml().load(reader); return document instanceof Map map && map.containsKey("bedrock-identity"); } } diff --git a/core/src/test/java/com/minekube/connect/config/ConfigLoaderTest.java b/core/src/test/java/com/minekube/connect/config/ConfigLoaderTest.java index e3943390d..e102b4de5 100644 --- a/core/src/test/java/com/minekube/connect/config/ConfigLoaderTest.java +++ b/core/src/test/java/com/minekube/connect/config/ConfigLoaderTest.java @@ -147,6 +147,33 @@ void loginReassertDefaultsToOnAndPropertiesOnly() throws Exception { "restoring the UUID needs an operator-side prerequisite, so it must be opt-in"); } + /** + * Velocity 4.x provides SnakeYAML 2.x at runtime (through Configurate), where the no-arg + * {@code SafeConstructor()} constructor was removed. 0.15.10 (PR #157) loaded an existing + * config.yml with {@code new Yaml(new SafeConstructor())}, so every existing-config load on + * Velocity crashed with NoSuchMethodError. The core test dependency pins SnakeYAML 2.x to + * reproduce that platform classpath; loading a legacy config must apply the safe Minekube + * defaults instead of crashing. + */ + @Test + void legacyConfigLoadsOnSnakeYaml2xRuntimeClasspath() throws Exception { + Files.writeString(tempDir.resolve("config.yml"), String.join("\n", + "endpoint: codexp2p3", + "allow-offline-mode-players: false", + "metrics:", + " disabled: true", + " uuid: 00000000-0000-0000-0000-000000000000", + "config-version: 1", + "")); + + ConnectConfig config = load(ConnectConfig.class); + + assertEquals("warn", config.getBedrockIdentity().getEnforcement()); + assertEquals( + "https://watch-connect.minekube.net/.well-known/minekube-connect/bedrock-identity-keys.json", + config.getBedrockIdentity().getMetadataUrl()); + } + /** Both halves are operator-controllable from the config file. */ @Test void loadsLoginReassertOverrides() throws Exception {