update java sdk#32
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
Code Review: Java SDK RefactoringOverviewThis PR is a major refactoring of the Java SDK, splitting it into two architectural layers:
The key architectural change is migrating from gRPC to OkHttp + Connect Protocol for runtime communication, removing the gRPC dependency. ~100 files changed, ~19,800 lines added. The bulk (~80%) is auto-generated OpenAPI code. Critical Issues (Must Fix)1. OkHttp Response body leak — resource/connection leak
try (Response response = httpClient.newCall(request).execute()) {
if (!response.isSuccessful()) {
throw new IOException("...");
}
Reader reader = response.body().charStream();
// ...
}2.
|
Follow-up Review (commits 9c5ccd3 + 6511b43)Thanks for addressing the feedback! Here's a summary of what was fixed and what remains. Addressed Issues ✅
Remaining IssuesCritical #3: Wrong error message in
|
furykerry
left a comment
There was a problem hiding this comment.
Code Review Summary
Files reviewed: ~100 files, ~19,800 lines. Hand-written: ConnectionConfig, E2bRuntimeConfig, Sandbox, SandboxApi, SandboxInfo, SandboxNotFoundException, RuntimeClient, RuntimeConfig, K8sHelper, EnvdMethods, Commands, CommandHandle, Filesystem, WatchHandle, WatchDirResponseObserver, ConnectStreamReader, MessageStream, K8sOperationException, SandboxException. Auto-generated (package rename only): envd/ protobuf code. Auto-generated (new): e2b/api/ OpenAPI client.
Note: This review builds on the two prior review rounds by @furykerry. Issues already addressed are not re-listed; only new or still-open findings are reported.
Critical
No new critical issues found. The previously identified critical issues (#1 OkHttp response leak, #2 RuntimeClient.close() empty, #3 Filesystem.getInfo() copy-paste error) have all been addressed in the follow-up commits. The getInfo() error message now correctly reads "Failed to get file info: " + path.
High
-
CommandHandle.close() — streamingResponse double-close will throw —
CommandHandle.javaclose()callsstreamReader.close()(wrapped in try-catch, good) thenstreamingResponse.close()(NOT wrapped). Forconnect()calls, the streamReader is aConnectResponseAdapterwhoseclose()already callsresponse.close(). SoCommandHandle.close()will callresponse.close()twice — the second call on an already-closed OkHttpResponsecan throwIllegalStateException. Fix: wrapstreamingResponse.close()in try-catch:if (streamingResponse != null) { try { streamingResponse.close(); } catch (Exception ignored) {} }
-
E2bRuntimeConfig.getSandboxURL() inconsistent with ConnectionConfig in PRIVATE mode —
E2bRuntimeConfig.javaIn PRIVATE mode,
E2bRuntimeConfig.getSandboxURL()returns justsandboxBaseURL(scheme://domain), whileConnectionConfig.getSandboxURL()returnsscheme://domain/kruise/<sandboxID>/<port>. The runtime layer usesgetSandboxURL()to build request URLs like{url}/{service}/{method}, so in PRIVATE mode the sandbox ID and port are missing from the URL path. This is likely a routing bug unless the gateway resolves it via headers — needs verification or alignment. -
RuntimeConfig TOCTOU race on shutdown flag —
RuntimeConfig.javagetOrCreateHttpClient()checksif (shutdown)outside thehttpClientLock. A thread can readshutdown == false, then another thread callsshutdown(), and the first thread proceeds to create a new client on a shut-down config. While unlikely in practice, the check should be inside thesynchronizedblock for correctness:public OkHttpClient getOrCreateHttpClient() { if (sharedHttpClient == null) { synchronized (httpClientLock) { if (shutdown) throw new IllegalStateException("..."); if (sharedHttpClient == null) { ... } } } return sharedHttpClient; }
Medium
-
WatchHandle.stop() uses System.err.println instead of Logger —
WatchHandle.java—Filesystemhas a properLogger LOG, butWatchHandle.stop()still writes toSystem.err.println. Use the Logger consistently. -
WatchDirResponseObserver.onError() uses System.err + printStackTrace —
WatchDirResponseObserver.java—System.err.println(...)andt.printStackTrace()should be replaced with a properLoggercall. -
ConnectResponseAdapter.close() doesn't protect response.close() —
Commands.java(inner class) —response.close()in the adapter'sclose()is not wrapped in try-catch. If it throws, it will propagate out ofclose(), which violates theCloseablecontract. -
Commands.sendSignal() error message says "Failed to send kill" —
Commands.java— The error message"Failed to send kill"is misleading — should be"Failed to send signal"since the method sends any signal, not just SIGKILL. -
Filesystem.watchDir() background thread not interruptible on shutdown —
Filesystem.java— The watch thread is a daemon (good), but callingRuntimeConfig.shutdown()doesn't close the streamingResponseheld byWatchHandle. If the user shuts down the config without callingwatchHandle.stop(), the thread may linger.
Low
-
Filesystem.urlEncode() uses deprecated "UTF-8" string — Use
StandardCharsets.UTF_8instead to avoid the unnecessary try-catch. -
RuntimeConfig.DEFAULT_AUTH_HEADER hardcoded base64 credential —
"Basic cm9vdDo="decodes toroot:. Not a leaked secret, but a weak default that could silently authenticate requests. Consider documenting prominently. -
No unit tests — ~19,800 lines of code with zero unit tests. Hand-written classes like
ConnectStreamReader,RuntimeConfig,E2bRuntimeConfig, andSandboxApishould have focused unit tests. -
MessageStream.java missing newline at end of file
Positive Findings
- Clean architecture split — E2B (control plane) and Runtime (data plane) separation is well-designed with clear package boundaries.
- All previously identified critical and high issues were addressed in follow-up commits.
- Double-checked locking done correctly in
ConnectionConfigandRuntimeConfig(volatile+synchronized). ConnectStreamReaderis well-implemented — proper frame length validation, trailer error parsing, max frame size guard.- Good error mapping in
SandboxApi— 404 →SandboxNotFoundException, 409 → idempotent success for pause. MessageStream<T>interface extraction is clean, enablingCommandHandleto work with both stream types uniformly.- Proper resource cleanup in error paths —
runBackground()andconnect()close bothstreamReaderandresponseon all error paths. - Bilingual documentation (English + Chinese READMEs) for both modules.
Verdict
REQUEST CHANGES — The double-close bug in CommandHandle.close() is a correctness issue that should be fixed before merge. The PRIVATE mode URL inconsistency needs verification. The remaining items are improvements that would strengthen reliability but don't block merge.
No description provided.