mirror of
https://github.com/layue13/MoonBridge.git
synced 2026-10-25 18:46:18 +00:00
build: 代理发行包改为单个可运行的 moonbridge.jar
发行包去掉 bin/ 启动脚本和 lib/ 下的 42 个依赖 jar,改为与其他代理服务端一样 用 java -jar moonbridge.jar 启动: - proxy-core 用 shadow 打出含全部依赖的 moonbridge.jar(合并 META-INF/services, 清单写入 Main-Class、Multi-Release 与 Enable-Native-Access: ALL-UNNAMED) - 泄漏检测默认关闭改由 ProxyMain 在加载 Netty 前设置,显式 -D 仍优先 - 移除不再使用的 application 约定插件 - 安装包检查、烟测与基准脚本改用发行包根目录作 classpath;文档同步 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
789648c82f
commit
afea023bce
23 files changed
+79
-99
No files matched your search
@@ -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.
|
||||
@@ -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`。
|
||||
|
||||
@@ -16,9 +16,5 @@ gradlePlugin {
|
||||
id = "moonbridge.publishing-conventions"
|
||||
implementationClass = "MoonBridgePublishingConventionsPlugin"
|
||||
}
|
||||
register("applicationConventions") {
|
||||
id = "moonbridge.application-conventions"
|
||||
implementationClass = "MoonBridgeApplicationConventionsPlugin"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.plugins.ApplicationPlugin
|
||||
|
||||
class MoonBridgeApplicationConventionsPlugin : Plugin<Project> {
|
||||
override fun apply(project: Project) {
|
||||
project.plugins.apply(MoonBridgeJavaLibraryConventionsPlugin::class.java)
|
||||
project.plugins.apply(ApplicationPlugin::class.java)
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
|
||||
+1
-1
@@ -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
|
||||
```
|
||||
|
||||
|
||||
+4
-3
@@ -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 秒。各期限届满可能使当前登录失败或关闭当前会话。
|
||||
|
||||
+4
-4
@@ -56,9 +56,9 @@ dependencies {
|
||||
|
||||
`:proxy-core:distZip` 生成 `proxy/core/build/distributions/moonbridge-<version>.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)。
|
||||
@@ -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://` 地址时需要 |
|
||||
|
||||
|
||||
+41
-56
@@ -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<Exec>("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<Exec>(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<Exec>("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<Exec>("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<Test>().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>("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")) {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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" \
|
||||
|
||||
@@ -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") }
|
||||
|
||||
@@ -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'
|
||||
}
|
||||
|
||||
@@ -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'
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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']});
|
||||
|
||||
Reference in new issue
Block a user