fix(core): align libp2p endpoint runtime constructor#62
Merged
Conversation
…deps Libp2pEndpoint loads the isolated Libp2pEndpointRuntime through Libp2pRuntimeLoader.classLoader() and resolves its constructor reflectively by exact signature. PR #57 (trusted Bedrock identity sessions) added BedrockIdentityReadiness and BedrockAdmissionCoordinator to the runtime constructor (now 8/9-arg) but left the wrapper's getDeclaredConstructor(...) lookup at the old 7-arg signature. The lookup therefore matches no constructor and throws NoSuchMethodException, so the wrapper sets runtime=null and logs "Failed to initialize Connect libp2p endpoint runtime". The endpoint never starts and every join fails downstream with "No available Browser Hub". This drift is JDK-independent: it reproduces identically on Java 21 and Java 26 (and jvm-libp2p/kotlin classes load fine on Java 26), so it is not an upstream jvm-libp2p incompatibility despite surfacing when a user upgraded to Java 26. Wire both Bedrock dependencies through Libp2pEndpoint's @Inject constructor (both are already provided in the same injector — the co-located eager singleton WatcherRegister injects them today) and extend the reflective lookup and newInstance to the 9-arg constructor. Add Libp2pEndpointRuntimeInitTest, which constructs the wrapper and asserts the runtime initializes; it fails (runtime==null) with the pre-fix 7-arg lookup and passes after. Document the reflective boundary contract in AGENTS.md.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
Fix Connect (connect-java) failing to initialize its libp2p endpoint runtime, reported by a user on Purpur 26.1.2 / Java 26.0.1 / Connect Spigot v0.12.1: the plugin logs 'Failed to initialize Connect libp2p endpoint runtime' with java.lang.NoSuchMethodException on Libp2pEndpointRuntime., the endpoint never starts, and every join fails with 'No available Browser Hub'. Root cause (proven, not the reported Java-26 theory): a JDK-INDEPENDENT constructor arity mismatch. PR #57 (trusted Bedrock identity sessions) added BedrockIdentityReadiness and BedrockAdmissionCoordinator to Libp2pEndpointRuntime's constructor (now 8/9-arg) but left Libp2pEndpoint's reflective getDeclaredConstructor(...) at the old 7-arg signature, so the reflective lookup across the isolated child-first classloader matches nothing and throws NoSuchMethodException, causing runtime=null. Verified by reproduction that this fails identically on Java 21 AND Java 26, and that jvm-libp2p/kotlin classes load fine on Java 26 — so it is NOT an upstream jvm-libp2p incompatibility and NOT fixed by a dependency bump, Java downgrade, or Gate-standalone workaround (all explicitly out of scope). Fix: add both Bedrock deps to Libp2pEndpoint's @Inject constructor (both are already provided in the same plugin injector — the co-located eager singleton WatcherRegister injects them today, so no startup regression) and extend the reflective lookup + newInstance to the real 9-arg constructor, passing the real BedrockAdmissionCoordinator (not the 8-arg null-coordinator overload). Added regression test Libp2pEndpointRuntimeInitTest that constructs the wrapper and asserts the runtime initializes (non-null); it was proven to fail with runtime==null under the pre-fix 7-arg lookup via a single-condition counterfactual and to pass after. Documented the reflective wrapper<->isolated-runtime boundary contract in AGENTS.md (a CLAUDE.md symlink was created by the project helper). Validated: real fixed wrapper yields a non-null Libp2pEndpointRuntime on both Java 21 and Java 26 with no error logged; full core suite of 249 tests passes; all platform modules (api/core/spigot/bungee/velocity) compile; Java 11 bytecode target preserved. This is a fix: commit (patch).
What Changed
Libp2pEndpointto inject Bedrock dependencies and resolve/invoke the isolated runtime’s nine-argument constructor.AGENTS.mdand linkedCLAUDE.mdto it.Risk Assessment
✅ Low: The updated change is well-bounded: production wiring matches the nine-argument runtime constructor, and the regression test now verifies the real admission coordinator crosses the isolated loader boundary and is closed afterward.
Testing
The focused runtime-init regression passed on Java 21 and Java 26, with the Java 26 Gradle test worker explicitly confirmed. Platform modules compiled successfully; the boundary guard passed; both relevant classes retained Java 11 bytecode (major 55) and matching 9-argument constructor descriptors. Gradle 8.5 itself cannot start directly on Java 26 due its embedded Kotlin parser, so Gradle ran on Java 21 while only the test worker used Java 26. No full suite or linters were run, and transient worktree build outputs were removed.
Evidence: Java 26 runtime initialization
Evidence: Java 21 test report
Evidence: Java 26 test report
Evidence: Java 11 bytecode and constructor evidence
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
🔧 **Review** - 1 issue found → auto-fixed ✅
core/src/test/java/com/minekube/connect/tunnel/p2p/Libp2pEndpointRuntimeInitTest.java:71- The test passes null for both Bedrock dependencies and only checksruntime != null. Because the runtime still has an 8-argument overload with a null coordinator, a regression to that overload would pass while bypassing Bedrock admission for libp2p sessions. Assert that the nine-argument constructor stores the real coordinator.🔧 Fix: Strengthen libp2p coordinator wiring regression test
✅ Re-checked - no issues remain.
✅ **Test** - passed
✅ No issues found.
./gradlew :core:test --tests com.minekube.connect.tunnel.p2p.Libp2pEndpointRuntimeInitTeston Java 21Focused test worker on Java 26 via temporary Gradle init configuration./gradlew :core:test --tests com.minekube.connect.tunnel.p2p.Libp2pRuntimeBoundaryTest./gradlew :api:compileJava :core:compileJava :spigot:compileJava :bungee:compileJava :velocity:compileJavajavap -verboseon Libp2pEndpoint and Libp2pEndpointRuntime classesFinalgit status --short --branchcleanup check✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.