diff --git a/CLAUDE.md b/CLAUDE.md index ce0898e..f753093 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -17,7 +17,7 @@ The LuckPerms platform plugin compiles LuckPerms from the `proxy/vendor/luckperm ./gradlew :proxy-core:test # proxy-core tests only ./gradlew :proxy-core:test --tests '*RawRelayTest' # one class ./gradlew :proxy-core:test --tests '*RawRelayTest.m' # one method -./gradlew :proxy-core:installDist # runnable distribution in proxy/core/build/install/moonbridge +./gradlew :proxy-core:installDist # proxy/core/build/install/moonbridge: java -jar moonbridge.jar ``` The slow tests are the session integration tests (`ProxySessionListenerTest`, `SessionTransferTest`, `InitialRoutingTest`, `SourceReleaseTransferTest`); iterate with `--tests` and run `check` once before pushing. @@ -57,7 +57,7 @@ testing/smoke/ smoke scripts and dated records; testing/benchmarks/ likewis **Transport.** `NetworkTransport` picks epoll / kqueue / NIO and supplies the channel types for the listener, backend dials and the DNS resolver together. Create event loops only through it: a bare `MultiThreadIoEventLoopGroup` silently uses a `LinkedBlockingQueue` instead of the MPSC queue, which showed up as a measurable per-frame cost. -**Buffer ownership.** Production runs with Netty leak detection disabled (the start script passes `-Dio.netty.leakDetection.level=disabled`), so refcounting must be right by construction. Do not write new `try/finally release()` blocks. Use `ByteBufs.fill/use` for allocate-write-release-on-failure, extend `FrameTransformHandler` for per-frame inbound handlers (its `transform` borrows the frame and returns what to forward), and use Netty's `MessageToMessageEncoder/Decoder` for codecs. Tests run every `proxy-core` test class under PARANOID leak detection: `LeakGate` (auto-registered via `junit-platform.properties`) fails a class that leaks a buffer. It cannot see `Unpooled.wrappedBuffer(byte[])` buffers, so assert `refCnt()` directly for those. +**Buffer ownership.** Production runs with Netty leak detection disabled (`ProxyMain` sets `io.netty.leakDetection.level=disabled` before Netty loads unless the property is given), so refcounting must be right by construction. Do not write new `try/finally release()` blocks. Use `ByteBufs.fill/use` for allocate-write-release-on-failure, extend `FrameTransformHandler` for per-frame inbound handlers (its `transform` borrows the frame and returns what to forward), and use Netty's `MessageToMessageEncoder/Decoder` for codecs. Tests run every `proxy-core` test class under PARANOID leak detection: `LeakGate` (auto-registered via `junit-platform.properties`) fails a class that leaks a buffer. It cannot see `Unpooled.wrappedBuffer(byte[])` buffers, so assert `refCnt()` directly for those. **Backends and plugins.** Backends come from static config, plugin registration (`Servers.register`, owner-scoped handles with generations) or the optional control channel (`BackendControlService`: separate authenticated blocking sockets on virtual threads, leases that outlive short disconnects). Initial routing is fail-closed: with no placement plugin it uses only `initialRouting.servers`. Permissions are a provider interface (`PermissionService`) with per-connection subjects that are prepared before login admission and released on any exit. @@ -68,4 +68,4 @@ testing/smoke/ smoke scripts and dated records; testing/benchmarks/ likewis ## Performance work -Benchmarks live in `testing/benchmarks/` (`ProxySessionBenchmark`, PowerShell runners; on Linux compile it against `proxy/core/build/install/moonbridge/lib` and run `java --enable-native-access=ALL-UNNAMED -cp ... dev.moonbridge.core.session.ProxySessionBenchmark --burst 32 --window 4 --transport epoll`). The existing records show the house method: set the decision rule first, rotate variant order across JVM runs, report median and range, keep raw output next to a dated `testing/benchmarks/results/*.md` that states what it does not cover, and prefer profile samples (JFR) over overlapping throughput ranges. Single-host loopback numbers are never capacity claims. +Benchmarks live in `testing/benchmarks/` (`ProxySessionBenchmark`, PowerShell runners; on Linux compile it against `proxy/core/build/install/moonbridge/moonbridge.jar` and run `java --enable-native-access=ALL-UNNAMED -cp ... dev.moonbridge.core.session.ProxySessionBenchmark --burst 32 --window 4 --transport epoll`). The existing records show the house method: set the decision rule first, rotate variant order across JVM runs, report median and range, keep raw output next to a dated `testing/benchmarks/results/*.md` that states what it does not cover, and prefer profile samples (JFR) over overlapping throughput ranges. Single-host loopback numbers are never capacity claims. diff --git a/README.md b/README.md index b8878df..fcf3a24 100644 --- a/README.md +++ b/README.md @@ -20,8 +20,8 @@ ```sh ./gradlew check :proxy-core:installDist # Windows: .\gradlew.bat check :proxy-core:installDist cd proxy/core/build/install/moonbridge -bin/moonbridge --validate-config config/moonbridge.yml # Windows: bin\moonbridge.bat -bin/moonbridge --config config/moonbridge.yml +java -jar moonbridge.jar --validate-config config/moonbridge.yml +java -jar moonbridge.jar # 默认读取 config/moonbridge.yml ``` 需要全部部署物(服务器包、后端插件、客户端 mod)时运行 `./gradlew release`,说明见[发行物与安装位置](docs/release-layout.md)。LuckPerms 平台插件从 `proxy/vendor/luckperms` 子模块编译,默认不构建;需要时先 `git submodule update --init --recursive`,再加 `-Pluckperms`。 diff --git a/build-logic/build.gradle.kts b/build-logic/build.gradle.kts index fda1796..51ba319 100644 --- a/build-logic/build.gradle.kts +++ b/build-logic/build.gradle.kts @@ -16,9 +16,5 @@ gradlePlugin { id = "moonbridge.publishing-conventions" implementationClass = "MoonBridgePublishingConventionsPlugin" } - register("applicationConventions") { - id = "moonbridge.application-conventions" - implementationClass = "MoonBridgeApplicationConventionsPlugin" - } } } diff --git a/build-logic/src/main/kotlin/MoonBridgeApplicationConventionsPlugin.kt b/build-logic/src/main/kotlin/MoonBridgeApplicationConventionsPlugin.kt deleted file mode 100644 index 9f461ba..0000000 --- a/build-logic/src/main/kotlin/MoonBridgeApplicationConventionsPlugin.kt +++ /dev/null @@ -1,10 +0,0 @@ -import org.gradle.api.Plugin -import org.gradle.api.Project -import org.gradle.api.plugins.ApplicationPlugin - -class MoonBridgeApplicationConventionsPlugin : Plugin { - override fun apply(project: Project) { - project.plugins.apply(MoonBridgeJavaLibraryConventionsPlugin::class.java) - project.plugins.apply(ApplicationPlugin::class.java) - } -} diff --git a/build.gradle.kts b/build.gradle.kts index 27d1c78..6db3f36 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,6 +1,5 @@ plugins { id("moonbridge.java-library-conventions") apply false - id("moonbridge.application-conventions") apply false } val releaseVersion = providers.gradleProperty("releaseVersion").orElse("0.1.0-SNAPSHOT").get() diff --git a/docs/mariadb.md b/docs/mariadb.md index f73177b..ef4273a 100644 --- a/docs/mariadb.md +++ b/docs/mariadb.md @@ -22,7 +22,7 @@ PDS、AetherShard 与 LuckPerms 可以使用同一台 MariaDB 服务,各自保 git submodule update --init --recursive bash ./gradlew clean check :proxy-core:distZip --no-daemon --max-workers=2 mkdir -p build/permission-network-classes -javac -cp 'proxy/core/build/install/moonbridge/lib/*' -d build/permission-network-classes testing/smoke/PermissionNetworkAcceptance.java +javac -cp 'proxy/core/build/install/moonbridge/*' -d build/permission-network-classes testing/smoke/PermissionNetworkAcceptance.java node testing/smoke/permission-services.cjs start ``` diff --git a/docs/operations.md b/docs/operations.md index 61689bc..0796a31 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -10,8 +10,9 @@ ```powershell .\gradlew.bat :proxy-core:installDist -.\proxy-core\build\install\moonbridge\bin\moonbridge.bat --validate-config .\proxy-core\build\install\moonbridge\config\moonbridge.yml -.\proxy-core\build\install\moonbridge\bin\moonbridge.bat --config .\proxy-core\build\install\moonbridge\config\moonbridge.yml +cd .\proxy\core\build\install\moonbridge +java -jar moonbridge.jar --validate-config config\moonbridge.yml +java -jar moonbridge.jar --config config\moonbridge.yml ``` `--validate-config` 校验核心 YAML、静态后端注册和服务器列表图标;它不会加载插件,所以不会验证已启用插件的设置、后端连通性或登录流程。未知核心配置键会报错。 @@ -44,7 +45,7 @@ status: - 可选的 `websocket` 段在 TCP `listen` 之外再开一个 WebSocket 玩家监听,供经 CDN 接入的客户端使用;两种入口同时可用,见 [WebSocket 接入](websocket.md)。OFFLINE 模式对 `websocket.listen` 同样要求字面量回环 IP,除非设置 `allowOfflinePublicAccess: true`。 - `maxConnections` 默认 4096,范围为 1–1,000,000;计数包括登录中的客户端,以及尚未完成 WebSocket 升级的连接。达到上限时新连接直接关闭。按部署资源和连接规模配置,不将其解释为后端容量。 - `transport` 选择玩家连接、后端连接和 DNS 使用的网络传输层,默认 `AUTO`:Linux 上用 epoll,macOS 上用 kqueue,其他平台(如 Windows)或原生库无法加载时(如 ARM/x86 以外的架构、musl 发行版)回退到 NIO,启动日志会输出实际选用的传输层。发行包附带 Linux x86_64/aarch64 的 epoll 与 macOS x86_64/aarch64 的 kqueue 原生库,启动脚本已加 `--enable-native-access=ALL-UNNAMED`。显式写 `NIO`、`EPOLL` 或 `KQUEUE` 会强制使用对应实现;指定的原生传输层不可用时启动失败,不会静默回退。后端控制通道使用独立的阻塞套接字,不受此项影响。 -- 发行包默认关闭 Netty 的内存泄漏检测(`-Dio.netty.leakDetection.level=disabled`):它在每个手写转发/编码路径上都有逐帧开销,合成基准中 burst 场景每帧 CPU 中位数约低 26%(范围有重叠,见[记录](../testing/benchmarks/results/2026-10-05-event-loop-queue-and-netty.md))。代替它的是测试期的 `LeakGate`:`proxy-core` 的每个测试类都以 PARANOID 级别运行,发现未释放的缓冲区即让该类失败,且有自测证明它能抓到故意的泄漏。引用计数的手写位置已集中到 `ByteBufs`、`FrameTransformHandler` 与 Netty 自带的编解码基类里;已评估的手写 release 位置都有测试守护,范围与方法见[验证说明](testing.md)。需要在某个部署上重新启用时,设置 `JAVA_OPTS=-Dio.netty.leakDetection.level=simple`(启动脚本里后出现的 `-D` 覆盖默认值)。 +- 发行包默认关闭 Netty 的内存泄漏检测(`-Dio.netty.leakDetection.level=disabled`):它在每个手写转发/编码路径上都有逐帧开销,合成基准中 burst 场景每帧 CPU 中位数约低 26%(范围有重叠,见[记录](../testing/benchmarks/results/2026-10-05-event-loop-queue-and-netty.md))。代替它的是测试期的 `LeakGate`:`proxy-core` 的每个测试类都以 PARANOID 级别运行,发现未释放的缓冲区即让该类失败,且有自测证明它能抓到故意的泄漏。引用计数的手写位置已集中到 `ByteBufs`、`FrameTransformHandler` 与 Netty 自带的编解码基类里;已评估的手写 release 位置都有测试守护,范围与方法见[验证说明](testing.md)。这个默认值由 `ProxyMain` 在加载 Netty 前设置;需要在某个部署上重新启用时,启动时传入 `java -Dio.netty.leakDetection.level=simple -jar moonbridge.jar`,显式给出的值优先。 - `plugins.eventTimeoutSeconds` 为统一事件链期限,默认 5 秒,可设为 1–30 秒。玩家准入事件按订阅注册顺序共享一个期限;无订阅者时跳过派发。准入队列容量为 128,最多 1024 个未决请求。队列饱和、超时、异常或空结果都会拒绝当前访问:连接准入阶段关闭 TCP 连接,玩家准入阶段返回通用错误文本;插件可通过显式拒绝结果提供登录断开原因。生命周期通知有独立的单线程 FIFO 队列,容量 128,最多一个事件正在派发;单事件链受同一事件期限约束。过载时尽力丢弃并聚合记录,不影响连接处理。 - 未认证帧上限为 4 KiB;后端 Login Success 后切换到协议 5 PLAY 帧上限。握手/身份验证与后端连接/登录各自有 15 秒期限;`initialRouting.timeoutSeconds` 默认 15 秒,可设为 1–120 秒,覆盖插件异步选服和所有候选服务器的 DNS/TCP 建连。`initialRouting.servers` 是无插件策略时显式配置的有序候选服务器名,最多 16 个;默认空列表会拒绝首次登录,不会从动态注册目录猜一个服务器。有初始选服插件时,该插件的选择完全接管路由,失败不会回退到配置列表。只有发送任何 Minecraft 握手/登录字节前的 DNS/TCP 失败可继续尝试候选;开始后端登录后失败会结束本次登录,不重放协议流量。成功登录后,客户端须在两分钟内完成首次 PLAY/Forge 握手。 - 登录拒绝、插件主动断开以及后端关闭/读失败的已提交前端写入最多排空等待 5 秒。转服切换阶段有 15 秒期限;Forge 客户端切换后目标握手最多等待 30 秒。各期限届满可能使当前登录失败或关闭当前会话。 diff --git a/docs/publishing.md b/docs/publishing.md index 091e55a..e37c8be 100644 --- a/docs/publishing.md +++ b/docs/publishing.md @@ -56,9 +56,9 @@ dependencies { `:proxy-core:distZip` 生成 `proxy/core/build/distributions/moonbridge-.zip`。CI 把这个 ZIP 作为 `moonbridge-development` 下载工件的一部分上传,保留 30 天;它不是 Maven 模块,也不自动成为 Git Release。解压后从发行包目录运行: -```powershell -.\bin\moonbridge.bat --validate-config .\config\moonbridge.yml -.\bin\moonbridge.bat --config .\config\moonbridge.yml +```sh +java -jar moonbridge.jar --validate-config config/moonbridge.yml +java -jar moonbridge.jar --config config/moonbridge.yml ``` -Linux/macOS 使用 `bin/moonbridge`。发行包根目录只有运行需要的内容:`bin/` 启动脚本、`lib/` 依赖、`config/` 配置模板、README,以及带 `-Pluckperms` 构建时的 `plugins/`。文档、验收与基准记录留在仓库里;后端宿主 jar 不在代理包内,见[发行物与安装位置](release-layout.md)。 +不带参数时读取当前目录下的 `config/moonbridge.yml`。发行包根目录只有运行需要的内容:可直接运行的 `moonbridge.jar`(含全部依赖,清单里已允许 Netty 加载 epoll/kqueue 本地库)、`config/` 配置模板、README,以及带 `-Pluckperms` 构建时的 `plugins/`。文档、验收与基准记录留在仓库里;后端宿主 jar 不在代理包内,见[发行物与安装位置](release-layout.md)。 diff --git a/docs/release-layout.md b/docs/release-layout.md index b6e7a52..79ab994 100644 --- a/docs/release-layout.md +++ b/docs/release-layout.md @@ -4,7 +4,7 @@ | 路径 | 是什么 | 装在哪里 | | --- | --- | --- | -| `server/moonbridge-<版本>.zip` | 代理发行包:`bin/` 启动脚本、`lib/`、`config/` 示例配置、README;带 `-Pluckperms` 构建时 `plugins/` 里含 LuckPerms 平台插件 | 代理服务器,解压后用 JDK 25 运行 `bin/moonbridge --config config/moonbridge.yml` | +| `server/moonbridge-<版本>.zip` | 代理发行包:可直接运行的 `moonbridge.jar`、`config/` 示例配置、README;带 `-Pluckperms` 构建时 `plugins/` 里含 LuckPerms 平台插件 | 代理服务器,解压后在该目录用 JDK 25 运行 `java -jar moonbridge.jar` | | `backend/moonbridge-backend-<版本>.jar` | 后端共享宿主 `MoonBridgeBackend`(Bukkit/Uranium 插件,Java 8),内含消息 API 与控制通道客户端 | 每台后端服务器的 `plugins/`;后端业务插件对它 `compileOnly` 并在 `plugin.yml` 里 `depend: [MoonBridgeBackend]` | | `client/moonbridgews-<版本>.jar` | 1.7.10 Forge WebSocket 客户端 mod | 玩家客户端 `mods/`,另需 UniMixins;只在使用 `ws://`/`wss://` 地址时需要 | diff --git a/proxy/core/build.gradle.kts b/proxy/core/build.gradle.kts index 7efe613..8a41186 100644 --- a/proxy/core/build.gradle.kts +++ b/proxy/core/build.gradle.kts @@ -1,7 +1,10 @@ +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar import org.gradle.api.tasks.Exec plugins { - id("moonbridge.application-conventions") + id("moonbridge.java-library-conventions") + distribution + id("com.gradleup.shadow") version "9.6.1" } val runtimeJavaHome = System.getProperty("java.home") @@ -37,54 +40,26 @@ dependencies { testImplementation(libs.findLibrary("netty-pkitesting").get()) } -val installedDistSmokeTest = tasks.register("installedDistSmokeTest") { - group = "verification" - description = "Runs the installed MoonBridge distribution in --validate-config mode." - dependsOn(tasks.named("installDist")) +// The distribution is started the way an operator starts it: java -jar moonbridge.jar from the install directory. +fun installedDistCheck(name: String, description: String, vararg arguments: String) = + tasks.register(name) { + group = "verification" + this.description = description + dependsOn(tasks.named("installDist")) - val installDir = layout.buildDirectory.dir("install/moonbridge") - inputs.dir(installDir) - environment("JAVA_HOME", runtimeJavaHome) - - doFirst { - val windows = System.getProperty("os.name").lowercase().contains("windows") - val script = installDir.get().file("bin/" + if (windows) "moonbridge.bat" else "moonbridge").asFile - val config = installDir.get().file("config/moonbridge.yml").asFile - commandLine(script.absolutePath, "--validate-config", config.absolutePath) + val installDir = layout.buildDirectory.dir("install/moonbridge") + inputs.dir(installDir) + workingDir(installDir) + commandLine(File(runtimeJavaHome, "bin/java").absolutePath, "-jar", "moonbridge.jar", *arguments) } -} -val installedDistHelpSmokeTest = tasks.register("installedDistHelpSmokeTest") { - group = "verification" - description = "Runs the installed MoonBridge distribution help command." - dependsOn(tasks.named("installDist")) - - val installDir = layout.buildDirectory.dir("install/moonbridge") - inputs.dir(installDir) - environment("JAVA_HOME", runtimeJavaHome) - - doFirst { - val windows = System.getProperty("os.name").lowercase().contains("windows") - val script = installDir.get().file("bin/" + if (windows) "moonbridge.bat" else "moonbridge").asFile - commandLine(script.absolutePath, "--help") - } -} - -val installedDistVersionSmokeTest = tasks.register("installedDistVersionSmokeTest") { - group = "verification" - description = "Runs the installed MoonBridge distribution version command." - dependsOn(tasks.named("installDist")) - - val installDir = layout.buildDirectory.dir("install/moonbridge") - inputs.dir(installDir) - environment("JAVA_HOME", runtimeJavaHome) - - doFirst { - val windows = System.getProperty("os.name").lowercase().contains("windows") - val script = installDir.get().file("bin/" + if (windows) "moonbridge.bat" else "moonbridge").asFile - commandLine(script.absolutePath, "--version") - } -} +val installedDistSmokeTest = installedDistCheck("installedDistSmokeTest", + "Runs the installed MoonBridge distribution in --validate-config mode.", + "--validate-config", "config/moonbridge.yml") +val installedDistHelpSmokeTest = installedDistCheck("installedDistHelpSmokeTest", + "Runs the installed MoonBridge distribution help command.", "--help") +val installedDistVersionSmokeTest = installedDistCheck("installedDistVersionSmokeTest", + "Runs the installed MoonBridge distribution version command.", "--version") // The benchmarks in testing/benchmarks/ declare proxy-core packages to reach package-private classes and are // normally compiled by their PowerShell runners. Compiling them here keeps them building with main. @@ -127,16 +102,6 @@ tasks.named("check") { dependsOn(compileBenchmarks) } -application { - mainClass.set("dev.moonbridge.app.ProxyMain") - applicationName = "moonbridge" - // Netty's epoll/kqueue transports load a JNI library; allow it without JDK restricted-method warnings. - // Leak detection is off in the distribution; every proxy-core test class runs with PARANOID detection - // through LeakGate instead. Re-enable per deployment with JAVA_OPTS=-Dio.netty.leakDetection.level=simple. - applicationDefaultJvmArgs = listOf("--enable-native-access=ALL-UNNAMED", - "-Dio.netty.leakDetection.level=disabled") -} - tasks.withType().configureEach { jvmArgs("--enable-native-access=ALL-UNNAMED") // Tests track every buffer so LeakGate can fail on a leak; the distribution runs with detection off. @@ -148,11 +113,31 @@ tasks.jar { manifest.attributes("Implementation-Title" to "MoonBridge", "Implementation-Version" to project.version) } +// The server ships as one runnable jar, like other Minecraft proxies: java -jar moonbridge.jar. +val serverJar = tasks.named("shadowJar") { + archiveFileName.set("moonbridge.jar") + // Netty, Jackson and Logback register implementations through META-INF/services. + mergeServiceFiles() + exclude("module-info.class", "META-INF/versions/*/module-info.class", + "META-INF/*.SF", "META-INF/*.DSA", "META-INF/*.RSA") + manifest.attributes( + "Main-Class" to "dev.moonbridge.app.ProxyMain", + "Implementation-Title" to "MoonBridge", + "Implementation-Version" to project.version, + // Jackson ships version-specific classes; keep them selected at runtime. + "Multi-Release" to "true", + // Netty's epoll/kqueue transports load a JNI library; allow it without restricted-method warnings. + "Enable-Native-Access" to "ALL-UNNAMED", + ) +} + distributions { main { + distributionBaseName.set("moonbridge") // Only what the proxy needs to run. Docs and test records stay in the repository, and the // backend jar ships separately in build/release/backend (see docs/release-layout.md). contents { + from(serverJar) from(rootProject.file("README.md")) if (luckPerms != null) { from(luckPerms.tasks.named("pluginJar")) { diff --git a/proxy/core/src/main/java/dev/moonbridge/app/ProxyMain.java b/proxy/core/src/main/java/dev/moonbridge/app/ProxyMain.java index a9d5092..0e90cb2 100644 --- a/proxy/core/src/main/java/dev/moonbridge/app/ProxyMain.java +++ b/proxy/core/src/main/java/dev/moonbridge/app/ProxyMain.java @@ -19,6 +19,15 @@ import java.util.concurrent.Executors; /** Command line entry point for the new proxy runtime. */ public final class ProxyMain { + static { + // Leak detection costs per frame on every hand-written forwarding path, so the proxy runs without it; + // every proxy-core test class runs with PARANOID detection through LeakGate instead. This must run + // before Netty is loaded. Re-enable per deployment with -Dio.netty.leakDetection.level=simple. + if (System.getProperty("io.netty.leakDetection.level") == null) { + System.setProperty("io.netty.leakDetection.level", "disabled"); + } + } + private static final Logger LOGGER = LoggerFactory.getLogger(ProxyMain.class); private ProxyMain() { diff --git a/testing/benchmarks/run-cipher.ps1 b/testing/benchmarks/run-cipher.ps1 index e1eded0..6ccfb6d 100644 --- a/testing/benchmarks/run-cipher.ps1 +++ b/testing/benchmarks/run-cipher.ps1 @@ -7,7 +7,7 @@ param( $ErrorActionPreference = "Stop" $repoRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot) -$installLib = Join-Path $repoRoot "proxy\core\build\install\moonbridge\lib" +$installLib = Join-Path $repoRoot "proxy\core\build\install\moonbridge" $classes = Join-Path $PSScriptRoot "build" Push-Location $repoRoot diff --git a/testing/benchmarks/run-proxy-session.ps1 b/testing/benchmarks/run-proxy-session.ps1 index 4fa8076..c405d19 100644 --- a/testing/benchmarks/run-proxy-session.ps1 +++ b/testing/benchmarks/run-proxy-session.ps1 @@ -13,7 +13,7 @@ param( $ErrorActionPreference = "Stop" $repoRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot) -$installLib = Join-Path $repoRoot "proxy\core\build\install\moonbridge\lib" +$installLib = Join-Path $repoRoot "proxy\core\build\install\moonbridge" $classes = Join-Path $PSScriptRoot "build" Push-Location $repoRoot diff --git a/testing/benchmarks/run-relay.ps1 b/testing/benchmarks/run-relay.ps1 index d462e0c..12a91a0 100644 --- a/testing/benchmarks/run-relay.ps1 +++ b/testing/benchmarks/run-relay.ps1 @@ -9,7 +9,7 @@ param( $ErrorActionPreference = "Stop" $repoRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot) -$installLib = Join-Path $repoRoot "proxy\core\build\install\moonbridge\lib" +$installLib = Join-Path $repoRoot "proxy\core\build\install\moonbridge" $classes = Join-Path $PSScriptRoot "build" Push-Location $repoRoot diff --git a/testing/benchmarks/run-transfer-paired.ps1 b/testing/benchmarks/run-transfer-paired.ps1 index 1c67a09..1f78c5b 100644 --- a/testing/benchmarks/run-transfer-paired.ps1 +++ b/testing/benchmarks/run-transfer-paired.ps1 @@ -6,7 +6,7 @@ param( $ErrorActionPreference = "Stop" $repoRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot) -$candidateLib = Join-Path $repoRoot "proxy\core\build\install\moonbridge\lib" +$candidateLib = Join-Path $repoRoot "proxy\core\build\install\moonbridge" $baselineLib = (Resolve-Path -LiteralPath $BaselineLibDirectory).Path if (-not (Test-Path -LiteralPath $baselineLib -PathType Container)) { throw "baseline library directory does not exist: $baselineLib" diff --git a/testing/benchmarks/run-transfer-path.ps1 b/testing/benchmarks/run-transfer-path.ps1 index bc6f082..a5b0546 100644 --- a/testing/benchmarks/run-transfer-path.ps1 +++ b/testing/benchmarks/run-transfer-path.ps1 @@ -7,7 +7,7 @@ param( $ErrorActionPreference = "Stop" $repoRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot) -$installLib = Join-Path $repoRoot "proxy\core\build\install\moonbridge\lib" +$installLib = Join-Path $repoRoot "proxy\core\build\install\moonbridge" $classes = Join-Path $PSScriptRoot "build" Push-Location $repoRoot diff --git a/testing/smoke/channel-java8.ps1 b/testing/smoke/channel-java8.ps1 index 73e0a03..835a6e8 100644 --- a/testing/smoke/channel-java8.ps1 +++ b/testing/smoke/channel-java8.ps1 @@ -6,9 +6,9 @@ $ErrorActionPreference = 'Stop' $repo = Split-Path -Parent (Split-Path -Parent $PSScriptRoot) $fixtureClasses = Join-Path $repo 'build/channel-smoke/router' $probeClasses = Join-Path $repo 'build/channel-smoke/probe' -$proxyClasspath = Join-Path $repo 'proxy/core/build/install/moonbridge/lib/*' +$proxyClasspath = Join-Path $repo 'proxy/core/build/install/moonbridge/*' $backendClasspath = Join-Path $repo 'backend/build/libs/*' -if (-not (Test-Path (Join-Path $repo 'proxy/core/build/install/moonbridge/lib'))) { +if (-not (Test-Path (Join-Path $repo 'proxy/core/build/install/moonbridge'))) { throw 'Run gradlew :proxy-core:installDist :backend:jar first.' } New-Item -ItemType Directory -Force $fixtureClasses, $probeClasses | Out-Null diff --git a/testing/smoke/container-channel.sh b/testing/smoke/container-channel.sh index ca4e0af..437e729 100644 --- a/testing/smoke/container-channel.sh +++ b/testing/smoke/container-channel.sh @@ -55,7 +55,7 @@ if [ "$ready" -ne 1 ]; then docker logs "$backend"; exit 1; fi docker run -d --network "$network" --name "$proxy" \ -v "$install:/opt/moonbridge:ro" -v "$work/config.yml:/opt/moonbridge.yml:ro" \ - --entrypoint java "$java_image" -cp '/opt/moonbridge/lib/*' \ + --entrypoint java "$java_image" -cp '/opt/moonbridge/*' \ dev.moonbridge.app.ProxyMain --config /opt/moonbridge.yml >/dev/null if ! docker run --rm --network "$network" -v "$repo_root:/work:ro" \ -e "MOONBRIDGE_CHANNEL_SECRET=$secret" --entrypoint python3 "$python_image" \ diff --git a/testing/smoke/container-network.ps1 b/testing/smoke/container-network.ps1 index ab00f95..09dc5a7 100644 --- a/testing/smoke/container-network.ps1 +++ b/testing/smoke/container-network.ps1 @@ -98,7 +98,7 @@ $controlConfig WaitBackend $backend InvokeDocker @('run', '-d', '--network', $network, '--name', $proxy, '-v', "${install}:/opt/moonbridge:ro", '-v', "${config}:/opt/moonbridge.yml:ro", - '--entrypoint', 'java', $javaImage, '-cp', '/opt/moonbridge/lib/*', + '--entrypoint', 'java', $javaImage, '-cp', '/opt/moonbridge/*', 'dev.moonbridge.app.ProxyMain', '--config', '/opt/moonbridge.yml') | Out-Null $clientArgs = @('run', '--rm', '--network', $network, '-v', "${repoRoot}:/work:ro") if ($mode -eq 'control') { $clientArgs += @('-e', "MOONBRIDGE_CHANNEL_SECRET=$secret") } diff --git a/testing/smoke/local-uranium-transfer.ps1 b/testing/smoke/local-uranium-transfer.ps1 index 0ffd65a..1c6c32b 100644 --- a/testing/smoke/local-uranium-transfer.ps1 +++ b/testing/smoke/local-uranium-transfer.ps1 @@ -26,7 +26,7 @@ if ($ReturnToOld -and -not $InstalledPlugin) { if (-not $PrismInstanceFolder) { $PrismInstanceFolder = $PrismInstance } $repoRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot) $bundle = (Resolve-Path -LiteralPath $BundlePath).Path -$proxyLib = Join-Path $repoRoot 'proxy\core\build\install\moonbridge\lib' +$proxyLib = Join-Path $repoRoot 'proxy\core\build\install\moonbridge' if (-not (Test-Path -LiteralPath $Java8Path) -or -not (Test-Path -LiteralPath $proxyLib)) { throw 'Java 8 and the installed MoonBridge distribution are required' } diff --git a/testing/smoke/local-uranium.ps1 b/testing/smoke/local-uranium.ps1 index ead4026..11bd766 100644 --- a/testing/smoke/local-uranium.ps1 +++ b/testing/smoke/local-uranium.ps1 @@ -25,7 +25,7 @@ $probeClasses = if ($PrismClient) { $null } else { if (-not $ProbeClassesPath) { throw 'ProbeClassesPath is required without -PrismClient' } (Resolve-Path -LiteralPath $ProbeClassesPath).Path } -$proxyLib = Join-Path $repoRoot 'proxy\core\build\install\moonbridge\lib' +$proxyLib = Join-Path $repoRoot 'proxy\core\build\install\moonbridge' if (-not (Test-Path -LiteralPath $Java8Path) -or -not (Test-Path -LiteralPath $proxyLib)) { throw 'Java 8 and the installed MoonBridge distribution are required' } diff --git a/testing/smoke/permission-client.ps1 b/testing/smoke/permission-client.ps1 index cc03e7f..f05def2 100644 --- a/testing/smoke/permission-client.ps1 +++ b/testing/smoke/permission-client.ps1 @@ -14,8 +14,8 @@ $bundle = (Resolve-Path -LiteralPath $BundlePath).Path $distribution = (Resolve-Path -LiteralPath $DistributionPath).Path $template = Join-Path (Join-Path $PrismCacheRoot 'instances') $PrismTemplateInstance $directHelper = Join-Path $PSScriptRoot 'permission-client-direct.cjs' -$distributionLib = Join-Path $distribution 'lib' -$proxyLib = Join-Path $distribution 'lib\*' +$distributionLib = $distribution +$proxyLib = Join-Path $distribution '*' $packagedPlugins = Join-Path $distribution 'plugins' $java25 = (Get-Command java.exe -ErrorAction Stop).Source $javac25 = (Get-Command javac.exe -ErrorAction Stop).Source diff --git a/testing/smoke/permission-network.cjs b/testing/smoke/permission-network.cjs index 644bbbc..314b90c 100644 --- a/testing/smoke/permission-network.cjs +++ b/testing/smoke/permission-network.cjs @@ -7,7 +7,7 @@ const mode = process.argv[2]; if (!['sql','redis'].includes(mode)) throw new Error('Usage: node testing/smoke/permission-network.cjs sql|redis [outage]'); const outage = process.argv[3] === 'outage'; const log = fs.createWriteStream(path.join(root,'build',`permission-network-${mode}${outage?'-outage':''}.log`)); -const args = ['-cp',`${path.join(root,'proxy/core/build/install/moonbridge/lib/*')}${path.delimiter}${path.join(root,'build/permission-network-classes')}`, +const args = ['-cp',`${path.join(root,'proxy/core/build/install/moonbridge/*')}${path.delimiter}${path.join(root,'build/permission-network-classes')}`, 'PermissionNetworkAcceptance','proxy/core/build/install/moonbridge',`build/permission-services/${mode==='sql'?'mariadb':'redis'}-base.yml`,'build/permission-network',mode]; if (outage) args.push('outage'); const child = spawn('java',args,{cwd:root,windowsHide:true,stdio:['pipe','pipe','pipe']});