Harden JVM runtime correctness - #180
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #180 +/- ##
==========================================
+ Coverage 86.60% 87.04% +0.44%
==========================================
Files 191 199 +8
Lines 17055 17858 +803
==========================================
+ Hits 14770 15544 +774
- Misses 2285 2314 +29 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR hardens JVM/runtime correctness by implementing proper object monitor semantics (reentrant enter/exit, wait/notify, and synchronized methods), serializing concurrent class initialization, and converting several previously-panicking paths (classfile parsing / native linkage) into Java-level exceptions. It also completes a few core Java API contracts around System, Thread, Object.clone, and UTF-16–based String operations.
Changes:
- Add reentrant monitors with wait/notify support and wire them into bytecode
monitorenter/monitorexit,Object.wait/notify, and synchronized methods. - Serialize class initialization with an owner/waiter model (including same-thread recursion) and broaden regression tests for initialization and monitor semantics.
- Harden classfile parsing and runtime linkage error handling (structured
ClassFileError, translate parser errors toClassFormatError/UnsupportedClassVersionError, and native calls toUnsatisfiedLinkError).
Reviewed changes
Copilot reviewed 48 out of 54 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| test_utils/src/lib.rs | Implements runtime yield/exit, logs spawned task failures, and maps classfile parse errors to Java exceptions for tests. |
| test_utils/Cargo.toml | Adds tracing dependency needed for new error logging. |
| test_data/src/NativeMethod.java | New E2E fixture for missing native method linkage. |
| test_data/src/MonitorSemantics.java | New E2E fixture validating synchronized + join + exception paths. |
| test_data/NativeMethod.txt | Expected output for NativeMethod fixture. |
| test_data/MonitorSemantics.txt | Expected output for MonitorSemantics fixture. |
| src/runtime.rs | Implements sleep/yield/exit/now and maps classfile parse errors to Java exceptions in the main runtime. |
| jvm/src/type.rs | Adds try_parse and tightens descriptor validation rules. |
| jvm/src/monitor.rs | Introduces a reentrant monitor with waiters + timeout-safe notifications. |
| jvm/src/lib.rs | Registers the new monitor module and exports wait/timeout types. |
| jvm/src/jvm.rs | Integrates monitors into JVM operations, adds shallow clone support, and serializes class initialization. |
| jvm/src/class_loader.rs | Implements class initialization owner/waiter state with completion notification. |
| jvm/src/class_instance.rs | Extends the core instance trait with identity() and shallow_clone(). |
| jvm/src/array_class_instance.rs | Plumbs identity() and shallow_clone() through array instances. |
| jvm_rust/src/method.rs | Maps missing bodies to UnsatisfiedLinkError / AbstractMethodError instead of panicking. |
| jvm_rust/src/lib.rs | Re-exports ClassFileError for downstream use. |
| jvm_rust/src/interpreter.rs | Implements monitorenter/monitorexit and NPE behavior for null monitors. |
| jvm_rust/src/class_instance.rs | Implements identity() and shallow cloning for object instances. |
| jvm_rust/src/class_definition.rs | Reworks classfile loading to return structured errors and validates more classfile invariants. |
| jvm_rust/src/array_class_instance.rs | Adds shallow cloning and identity for array instances. |
| java_runtime/tests/classes/java/lang/test_system.rs | Adds tests for System.currentTimeMillis, Thread.yield, and System.exit runtime contract. |
| java_runtime/tests/classes/java/lang/test_string.rs | Adds UTF-16 indexing, charset error, and trim contract tests. |
| java_runtime/tests/classes/java/lang/test_object.rs | Updates wait/notify tests for monitor-ownership requirements and adds clone semantics tests. |
| java_runtime/tests/classes/java/lang/test_class.rs | Adds tests for ClassLoader.findClass and defineClass error translation and bounds validation. |
| java_runtime/tests/classes/java/lang/test_class_initialization.rs | New concurrency tests for class initialization owner/waiter behavior and failure propagation. |
| java_runtime/tests/classes/java/lang/mod.rs | Wires new test modules into the test suite. |
| java_runtime/src/runtime.rs | Extends the runtime trait with exit(status). |
| java_runtime/src/loader.rs | Registers new runtime exception classes for linkage/format/version errors. |
| java_runtime/src/classes/java/lang/unsupported_class_version_error.rs | Adds UnsupportedClassVersionError runtime class implementation. |
| java_runtime/src/classes/java/lang/unsatisfied_link_error.rs | Adds UnsatisfiedLinkError runtime class implementation. |
| java_runtime/src/classes/java/lang/thread.rs | Makes start/join synchronized and improves join/cleanup behavior. |
| java_runtime/src/classes/java/lang/system.rs | Implements System.exit via the runtime exit hook. |
| java_runtime/src/classes/java/lang/string.rs | Aligns multiple string operations with UTF-16 indexing and adds proper charset error handling. |
| java_runtime/src/classes/java/lang/object.rs | Implements shallow clone and correct monitor-based wait/notify behavior with timeout safety. |
| java_runtime/src/classes/java/lang/class_loader.rs | Implements findClass throwing and validates defineClass byte ranges and nulls. |
| java_runtime/src/classes/java/lang/class_format_error.rs | Adds ClassFormatError runtime class implementation. |
| java_runtime/src/classes/java/lang.rs | Exports and wires the new java.lang error classes. |
| classfile/tests/test.rs | Adds structured error tests for malformed/unsupported class files. |
| classfile/src/opcode.rs | Rejects invalid opcodes/refs and tightens parsing to return errors instead of panicking. |
| classfile/src/method.rs | Makes parsing resilient to invalid access flags / constant pool lookups. |
| classfile/src/lib.rs | Exposes the new ClassFileError type. |
| classfile/src/interface.rs | Makes interface parsing resilient to invalid constant pool indices/types. |
| classfile/src/field.rs | Makes field parsing resilient to invalid access flags / constant pool lookups. |
| classfile/src/error.rs | Introduces ClassFileError (invalid format / unsupported version). |
| classfile/src/constant_pool.rs | Removes panics, validates counts/slot rules, and returns Option for typed constant pool lookups. |
| classfile/src/class.rs | Converts ClassInfo::parse to structured errors and enforces version bounds. |
| classfile/src/attribute.rs | Makes attribute parsing fail-fast on malformed constant pool references/opcodes. |
| Cargo.toml | Adds workspace tracing and enables Tokio time feature where needed. |
| Cargo.lock | Locks in tracing dependency additions. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8a2e4561f0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Judged the two remaining remote branches on the fork: - dependabot/cargo/tracing-attributes-0.1.31: deleted. PR #4 (fa92ef9) removed the tracing-attributes direct dependency outright, so the branch patches a Cargo.toml line that no longer exists. - wie-ktf-hardening: preserved. 8 of its 12 commits are already in upstream/main via squash merges (dlunch#174 dlunch#175 dlunch#176 dlunch#177 dlunch#180 dlunch#182); git cherry missed this because origin/main trails upstream/main by 20 commits. 4 commits carry residual value. No code changes. Co-authored-by: jun0 <junyoung.choi.a@miraeasset.com> Co-authored-by: Claude <noreply@anthropic.com>
…oal/Constraints/DoD 감사(audit-agent-instructions-2026-08-05) §3-2·§3-3·§6 이행. 지침 파일만 변경 — 소스·빌드·CI 무접촉. C1 autonomous-sop 정리: 4 repo 동일 사본 중 현세대 잉여 1줄 삭제(세션 시작 시 STATE.md·git status 읽기 / 진행분 자율 이어받기 — 둘 다 harness·상위 헌장 기본값). "STATE.md 없으면 생성한다"도 함께 제거 — STATE.md·REPORT.md 는 실재하고 최근 3커밋에서 갱신돼 왔으므로 사문(死文)이다. 나머지 4줄(STATE 갱신·REPORT append·클라우드 금지· 체크포인트/force-push 금지)은 repo 고유 제약이라 보존. C2 「티켓 없는 착수 금지」: 문장은 유지하고 qts 판본의 한계 서술을 이식 — 이 규율은 자기신고형이고 티켓 파일에 provenance 가 없어 검증기로 막을 수 없다(1차 방어이며 최종 방어는 diff 검토). 홈 헌장 포인터로의 대체는 orch 레인 동결 해제 후 후속 몫. C3 구조: Goal/Constraints/DoD 골격 도입. Goal 에 연방 경계 2건을 명시 — RustJava 는 wie 의 비벤더 upstream 의존성이라 플랫폼이 직접 손대지 않는다(정본 = otterpebble .claude/rules/repo-boundaries.md #4), 그리고 이 repo 는 dlunch/RustJava 의 포크라 upstream 발신은 티켓 명시 허가 시에만 하고 gh 호출에 -R Jun025/RustJava 를 붙인다 (2026-07-22 오발행 사고). 둘 다 지금까지 지침에 없어 티켓마다 재기술돼 왔다. AGENTS.md 는 무접촉 — §Git Workflow 의 `-D` 강제 이유 보존. 연방 고유 내용을 CLAUDE.md 쪽에만 둔 것은 의도적이다: AGENTS.md 는 upstream 도 유지·편집하는 파일이라 (upstream 이 dlunch#180 에서 §Testing Boundaries 를 추가했다) 로컬 내용을 넣으면 동기화 충돌면이 넓어진다. 검증: cargo fmt --check rc=0 · cargo clippy --workspace --all-targets rc=0(경고 0) · cargo test --workspace rc=0(148 passed, 0 failed). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…t limits + Goal/Constraints/DoD (#8) * [rustjava-claude-md-prune] docs: prune autonomous-sop, add limits + Goal/Constraints/DoD 감사(audit-agent-instructions-2026-08-05) §3-2·§3-3·§6 이행. 지침 파일만 변경 — 소스·빌드·CI 무접촉. C1 autonomous-sop 정리: 4 repo 동일 사본 중 현세대 잉여 1줄 삭제(세션 시작 시 STATE.md·git status 읽기 / 진행분 자율 이어받기 — 둘 다 harness·상위 헌장 기본값). "STATE.md 없으면 생성한다"도 함께 제거 — STATE.md·REPORT.md 는 실재하고 최근 3커밋에서 갱신돼 왔으므로 사문(死文)이다. 나머지 4줄(STATE 갱신·REPORT append·클라우드 금지· 체크포인트/force-push 금지)은 repo 고유 제약이라 보존. C2 「티켓 없는 착수 금지」: 문장은 유지하고 qts 판본의 한계 서술을 이식 — 이 규율은 자기신고형이고 티켓 파일에 provenance 가 없어 검증기로 막을 수 없다(1차 방어이며 최종 방어는 diff 검토). 홈 헌장 포인터로의 대체는 orch 레인 동결 해제 후 후속 몫. C3 구조: Goal/Constraints/DoD 골격 도입. Goal 에 연방 경계 2건을 명시 — RustJava 는 wie 의 비벤더 upstream 의존성이라 플랫폼이 직접 손대지 않는다(정본 = otterpebble .claude/rules/repo-boundaries.md #4), 그리고 이 repo 는 dlunch/RustJava 의 포크라 upstream 발신은 티켓 명시 허가 시에만 하고 gh 호출에 -R Jun025/RustJava 를 붙인다 (2026-07-22 오발행 사고). 둘 다 지금까지 지침에 없어 티켓마다 재기술돼 왔다. AGENTS.md 는 무접촉 — §Git Workflow 의 `-D` 강제 이유 보존. 연방 고유 내용을 CLAUDE.md 쪽에만 둔 것은 의도적이다: AGENTS.md 는 upstream 도 유지·편집하는 파일이라 (upstream 이 dlunch#180 에서 §Testing Boundaries 를 추가했다) 로컬 내용을 넣으면 동기화 충돌면이 넓어진다. 검증: cargo fmt --check rc=0 · cargo clippy --workspace --all-targets rc=0(경고 0) · cargo test --workspace rc=0(148 passed, 0 failed). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * [rustjava-claude-md-prune-fix] docs: 머지 집행 주체 1줄 정정 (게이트② 검수자 동턴 집행) --------- Co-authored-by: jun0 <junyoung.choi.a@miraeasset.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Summary
Why
Several Java 1.2 and CLDC execution paths could panic in Rust, lose monitor or class-initialization wakeups, or violate Java API contracts. This keeps failures in Java exception flow and makes concurrent behavior deterministic.
Validation
cargo test --workspace --no-fail-fastcargo clippy --workspace --all-targets -- -D warningscargo fmt --all -- --check