From d58cdd0d88610f4c36c714940029639c47550f65 Mon Sep 17 00:00:00 2001 From: claude Date: Mon, 18 May 2026 12:19:39 +0000 Subject: [PATCH 1/5] build: target latest Minestom, align Butterfly, harden shaded jar, pin CI - Pin net.minestom:minestom to 2026.05.17-1.21.11 (current Maven Central release) instead of the BOM-resolved version so the deployable jar runs on the latest Minestom regardless of aonyx/mycelium BOM lag. - Bump butterfly 1.0.21 -> 1.0.23 to match the current Butterfly release. - Harden the application shadowJar: strip jar signatures and module-info and exclude duplicates so the relocation-free fat jar built from the shaded LuckPerms fork stays loadable. - Pin the reusable PR/publish workflows to the v2.1.0 release tag instead of a temporary branch ref. https://claude.ai/code/session_01S76fk9ma5Szkf9r1W44RVP --- .github/workflows/build-pr.yml | 2 +- .github/workflows/publish.yaml | 2 +- app/build.gradle.kts | 5 +++++ settings.gradle.kts | 4 ++-- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index 7326072..007d472 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -3,5 +3,5 @@ on: [pull_request] jobs: build: - uses: OneLiteFeatherNET/workflows/.github/workflows/gradle-build-pr.yml@claude/implement-release-please-9inVJ + uses: OneLiteFeatherNET/workflows/.github/workflows/gradle-build-pr.yml@v2.1.0 secrets: inherit diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index 6bc704d..8cfb25c 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -5,5 +5,5 @@ on: jobs: publish: - uses: OneLiteFeatherNET/workflows/.github/workflows/gradle-publish.yml@v2.0.0 + uses: OneLiteFeatherNET/workflows/.github/workflows/gradle-publish.yml@v2.1.0 secrets: inherit diff --git a/app/build.gradle.kts b/app/build.gradle.kts index c234cdc..b95c6c5 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -61,6 +61,11 @@ tasks { archiveClassifier.set("") archiveFileName.set("app-titan.jar") mergeServiceFiles() + // LuckPerms `common` pulls signed and multi-release jars that break a + // relocation-free application fat jar; drop signatures and module-info. + exclude("META-INF/*.SF", "META-INF/*.DSA", "META-INF/*.RSA") + exclude("module-info.class", "META-INF/versions/**/module-info.class") + duplicatesStrategy = DuplicatesStrategy.EXCLUDE } test { useJUnitPlatform() diff --git a/settings.gradle.kts b/settings.gradle.kts index 0440b26..a979074 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -29,7 +29,7 @@ dependencyResolutionManagement { version("aonyx-bom", "0.7.1") version("mycelium-bom", "1.6.4") version("cloudnet", "4.0.0-RC17-SNAPSHOT") - version("butterfly", "1.0.21") + version("butterfly", "1.0.23") version("luckperms", "5.6-SNAPSHOT") @@ -43,7 +43,7 @@ dependencyResolutionManagement { // Minestom library("aonyx-bom", "net.onelitefeather", "aonyx-bom").versionRef("aonyx-bom") library("mycelium-bom", "net.onelitefeather", "mycelium-bom").versionRef("mycelium-bom") - library("minestom","net.minestom", "minestom").withoutVersion() + library("minestom","net.minestom", "minestom").version("2026.05.17-1.21.11") library("aves", "net.theevilreaper", "aves").version("1.9.0") library("adventure.minimessage", "net.kyori", "adventure-text-minimessage").withoutVersion() library("butterfly-minestom", "net.onelitefeather", "butterfly-minestom").versionRef("butterfly") From d844f804c653ef9844ec503eda16c4cb54375e85 Mon Sep 17 00:00:00 2001 From: claude Date: Tue, 19 May 2026 08:51:44 +0000 Subject: [PATCH 2/5] fix(luckperms): load via JarInJar minestom-loader instead of raw shading Titan shaded net.luckperms common/minestom/minestom-app/loader-utils into the relocation-free fat jar and bootstrapped LPMinestomBootstrap directly on the app classpath, defeating LuckPerms' dependency isolation. Switch to the LuckPerms-designed loader: - depend on net.luckperms:minestom-loader (runtimeOnly, not shaded) - net.luckperms:api becomes a runtime (implementation) dependency so LuckPermsProvider resolves on the host classpath while the JarInJar child loads the isolated implementation against the same API classes - drop Titan's custom MinestomLoader; TitanApplication now uses the fork's me.lucko.luckperms.minestom.loader.MinestomLoader - add the minestom-loader version catalog entry - generalise the shadowJar signature/module-info hardening comment https://claude.ai/code/session_01S76fk9ma5Szkf9r1W44RVP --- app/build.gradle.kts | 9 +-- .../titan/app/TitanApplication.java | 2 +- .../titan/app/luckperms/MinestomLoader.java | 57 ------------------- settings.gradle.kts | 1 + 4 files changed, 5 insertions(+), 64 deletions(-) delete mode 100644 app/src/main/java/net/onelitefeather/titan/app/luckperms/MinestomLoader.java diff --git a/app/build.gradle.kts b/app/build.gradle.kts index b95c6c5..0a6f586 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -6,7 +6,7 @@ plugins { } dependencies { - compileOnly(libs.luckperms.api) + implementation(libs.luckperms.api) implementation(project(":api")) implementation(project(":common")) implementation(platform(libs.mycelium.bom)) @@ -18,10 +18,7 @@ dependencies { implementation(libs.minestom) implementation(libs.butterfly.minestom) - implementation(libs.luckperms.common) - implementation(libs.luckperms.common.loader.utils) - implementation(libs.luckperms.minestom.app) - implementation(libs.luckperms.minestom) + runtimeOnly(libs.luckperms.minestom.loader) implementation(platform(libs.cloudnet.bom)) implementation(libs.cloudnet.jvm.wrapper) @@ -61,7 +58,7 @@ tasks { archiveClassifier.set("") archiveFileName.set("app-titan.jar") mergeServiceFiles() - // LuckPerms `common` pulls signed and multi-release jars that break a + // Shaded deps ship signed and multi-release jars that break a // relocation-free application fat jar; drop signatures and module-info. exclude("META-INF/*.SF", "META-INF/*.DSA", "META-INF/*.RSA") exclude("module-info.class", "META-INF/versions/**/module-info.class") diff --git a/app/src/main/java/net/onelitefeather/titan/app/TitanApplication.java b/app/src/main/java/net/onelitefeather/titan/app/TitanApplication.java index a745f6c..abacc45 100644 --- a/app/src/main/java/net/onelitefeather/titan/app/TitanApplication.java +++ b/app/src/main/java/net/onelitefeather/titan/app/TitanApplication.java @@ -18,7 +18,7 @@ import eu.cloudnetservice.driver.inject.InjectionLayer; import eu.cloudnetservice.modules.bridge.impl.platform.minestom.MinestomBridgeExtension; import net.minestom.server.MinecraftServer; -import net.onelitefeather.titan.app.luckperms.MinestomLoader; +import me.lucko.luckperms.minestom.loader.MinestomLoader; public class TitanApplication { diff --git a/app/src/main/java/net/onelitefeather/titan/app/luckperms/MinestomLoader.java b/app/src/main/java/net/onelitefeather/titan/app/luckperms/MinestomLoader.java deleted file mode 100644 index 6d02a54..0000000 --- a/app/src/main/java/net/onelitefeather/titan/app/luckperms/MinestomLoader.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Copyright 2025 OneLiteFeather Network - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package net.onelitefeather.titan.app.luckperms; - - -import me.lucko.luckperms.minestom.LPMinestomBootstrap; -import me.lucko.luckperms.minestom.app.LuckPermsApplication; - -public final class MinestomLoader { - private static final LuckPermsApplication APPLICATION = new LuckPermsApplication(); - private static MinestomLoader instance; - private final LPMinestomBootstrap plugin; - - public MinestomLoader() { - this.plugin = new LPMinestomBootstrap(APPLICATION); - } - - public MinestomLoader registerShutdownHook() { - Runtime.getRuntime().addShutdownHook(new Thread(this.plugin::onDisable, "luckperms-shutdown-hook")); - return this; - } - - public MinestomLoader load() { - this.plugin.onLoad(); - return this; - } - - public void start() { - this.plugin.onEnable(); - } - - public static MinestomLoader get() { - MinestomLoader localInstance = instance; - if (localInstance != null) { - return localInstance; - } - synchronized (MinestomLoader.class) { - if (instance == null) { - instance = new MinestomLoader(); - } - return instance; - } - } -} diff --git a/settings.gradle.kts b/settings.gradle.kts index a979074..abf69ba 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -69,6 +69,7 @@ dependencyResolutionManagement { library("luckperms.minestom.app", "net.luckperms", "minestom-app").versionRef("luckperms") library("luckperms.common", "net.luckperms", "common").versionRef("luckperms") library("luckperms.common.loader.utils", "net.luckperms", "loader-utils").versionRef("luckperms") + library("luckperms.minestom.loader", "net.luckperms", "minestom-loader").versionRef("luckperms") library("cyano", "net.onelitefeather", "cyano").withoutVersion() library("mockito", "org.mockito", "mockito-core").versionRef("mockito") From effde8fe1a7536dc658ca9bcc48d87d05cac0c95 Mon Sep 17 00:00:00 2001 From: claude Date: Tue, 19 May 2026 08:54:55 +0000 Subject: [PATCH 3/5] fix(build): minestom-loader must be on the compile classpath TitanApplication references me.lucko.luckperms.minestom.loader.MinestomLoader directly, so the loader is needed at compile time; runtimeOnly removed it from compileClasspath and broke compilation. Use implementation: the minestom-loader artifact is a thin JarInJar wrapper with no heavy transitive dependencies (adventure/configurate live inside the embedded luckperms-minestom.jarinjar resource), so this does not reintroduce raw shading of common/minestom. https://claude.ai/code/session_01S76fk9ma5Szkf9r1W44RVP --- app/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 0a6f586..16db3ee 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -18,7 +18,7 @@ dependencies { implementation(libs.minestom) implementation(libs.butterfly.minestom) - runtimeOnly(libs.luckperms.minestom.loader) + implementation(libs.luckperms.minestom.loader) implementation(platform(libs.cloudnet.bom)) implementation(libs.cloudnet.jvm.wrapper) From da616e9f1d7bd2798d3b7006ae6421570dda8887 Mon Sep 17 00:00:00 2001 From: claude Date: Tue, 19 May 2026 09:21:06 +0000 Subject: [PATCH 4/5] fix(test): bump aonyx-bom to 0.7.2 for Minestom 2026.05.17-1.21.11 Pinning Minestom to 2026.05.17-1.21.11 decoupled it from the OLF BOM that also governs the cyano test harness; cyano 0.7.1 was built against an older Minestom, so RegistryData's static initializer threw NoSuchMethodError and all Minestom-backed tests failed. aonyx-bom 0.7.2 aligns cyano with Minestom 2026.05.17-1.21.11. https://claude.ai/code/session_01S76fk9ma5Szkf9r1W44RVP --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index abf69ba..c5e5b40 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -26,7 +26,7 @@ dependencyResolutionManagement { versionCatalogs { create("libs") { - version("aonyx-bom", "0.7.1") + version("aonyx-bom", "0.7.2") version("mycelium-bom", "1.6.4") version("cloudnet", "4.0.0-RC17-SNAPSHOT") version("butterfly", "1.0.23") From c26dae72a6dc403ce7a92a73302f3a7bf627228c Mon Sep 17 00:00:00 2001 From: claude Date: Wed, 20 May 2026 20:18:31 +0000 Subject: [PATCH 5/5] fix(build): switch mycelium-bom from enforcedPlatform to platform enforcedPlatform(mycelium-bom) pinned net.kyori:adventure-* classpath- wide; the pinned Adventure was older than Minestom 2026.05.17-1.21.11 requires, so MinestomFlattenerProvider. failed with NoSuchMethodError: ComponentFlattener.toBuilder(). Switching to platform(...) keeps the BOM as a version recommendation that Gradle can upgrade to satisfy Minestom's transitive Adventure version requirement. Applied in :common and :setup, the two modules using enforcedPlatform. https://claude.ai/code/session_01S76fk9ma5Szkf9r1W44RVP --- common/build.gradle.kts | 2 +- setup/build.gradle.kts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/common/build.gradle.kts b/common/build.gradle.kts index 3a81c71..797fdd1 100644 --- a/common/build.gradle.kts +++ b/common/build.gradle.kts @@ -5,7 +5,7 @@ plugins { dependencies { implementation(project(":api")) - implementation(enforcedPlatform(libs.mycelium.bom)) + implementation(platform(libs.mycelium.bom)) implementation(platform(libs.aonyx.bom)) implementation(libs.minestom) implementation(libs.togglz) diff --git a/setup/build.gradle.kts b/setup/build.gradle.kts index 3a84e59..372149a 100644 --- a/setup/build.gradle.kts +++ b/setup/build.gradle.kts @@ -9,7 +9,7 @@ plugins { dependencies { implementation(project(":common")) implementation(project(":api")) - implementation(enforcedPlatform(libs.mycelium.bom)) + implementation(platform(libs.mycelium.bom)) implementation(platform(libs.aonyx.bom)) implementation(libs.minestom) implementation(libs.togglz)