[GH-ISSUE #893] JADX provider OOMs on real-world multidex APK (11 dex, 133MB) #361

Closed
opened 2026-10-15 18:24:17 +00:00 by bsakaguchi · 2 comments
Owner

Originally created by @juxtapo9090 on GitHub (Oct 7, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/893

Summary

search_android_classes and inspect_android_package both fail with Java heap space on a production APK (133MB, 11 dex files). Tested with JAVA_TOOL_OPTIONS=-Xmx8g — same result. The env var reaches REA's MCP process but does not appear to propagate to the JADX subprocess.

Environment

  • REA: rea-agents@4.1.0
  • jadx-headless-mcp: 0.7.1 (SHA256 matches JADX_RELEASE in source)
  • Java: OpenJDK 25.0.4.1
  • OS: Fedora 44, 32GB RAM
  • Claude Code MCP integration

Steps

npx rea-agents@latest setup --client claude_code --yes
# Set env in .claude.json mcpServers.rea.env
# REA_JADX_MCP_JAR=/opt/jadx/jadx-headless-mcp-0.7.1-all.jar
# JAVA_TOOL_OPTIONS=-Xmx8g

Then via MCP:

search_android_classes(path="/path/to/app.apk", query="UserManager")

Error

{
  "code": "execution_failure",
  "details": {
    "provider_id": "jadx",
    "operation": "search_android_classes",
    "diagnostics": {
      "upstream_operation": "load_apk",
      "reason": "load failed: Java heap space"
    }
  }
}

APK characteristics

  • 133MB total
  • 11 DEX files (multidex)
  • Real production app from Play Store
  • Not obfuscated beyond standard ProGuard

Observations

  1. JAVA_TOOL_OPTIONS=-Xmx8g is confirmed picked up when running the JAR directly (Picked up JAVA_TOOL_OPTIONS: -Xmx8g), but the OOM persists through REA's MCP layer — suggests the subprocess env isn't inheriting the parent's env vars, or the JAR itself caps heap internally.

  2. The JAR manifest has no JVM flags (Main-Class: com.atxx.jhmcp.MainKt, nothing else).

  3. Same failure on 8GB explicit heap with 32GB system RAM — the APK genuinely needs more than JADX's default allocation, and there's no documented way to control heap for the JADX subprocess spawned by REA.

Expected

Either:

  • REA propagates JAVA_TOOL_OPTIONS / _JAVA_OPTIONS to the JADX subprocess
  • A REA_JADX_JAVA_OPTS env var for explicit control
  • Graceful degradation: partial-load or per-dex analysis instead of loading all 11 dex files at once

Large multidex APKs are common in production (banking, logistics, super-apps). A reverse engineering tool that can't open them is limited to demos and CTFs.

Originally created by @juxtapo9090 on GitHub (Oct 7, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/893 ## Summary `search_android_classes` and `inspect_android_package` both fail with `Java heap space` on a production APK (133MB, 11 dex files). Tested with `JAVA_TOOL_OPTIONS=-Xmx8g` — same result. The env var reaches REA's MCP process but does not appear to propagate to the JADX subprocess. ## Environment - REA: `rea-agents@4.1.0` - jadx-headless-mcp: `0.7.1` (SHA256 matches `JADX_RELEASE` in source) - Java: OpenJDK 25.0.4.1 - OS: Fedora 44, 32GB RAM - Claude Code MCP integration ## Steps ```bash npx rea-agents@latest setup --client claude_code --yes # Set env in .claude.json mcpServers.rea.env # REA_JADX_MCP_JAR=/opt/jadx/jadx-headless-mcp-0.7.1-all.jar # JAVA_TOOL_OPTIONS=-Xmx8g ``` Then via MCP: ``` search_android_classes(path="/path/to/app.apk", query="UserManager") ``` ## Error ```json { "code": "execution_failure", "details": { "provider_id": "jadx", "operation": "search_android_classes", "diagnostics": { "upstream_operation": "load_apk", "reason": "load failed: Java heap space" } } } ``` ## APK characteristics - 133MB total - 11 DEX files (multidex) - Real production app from Play Store - Not obfuscated beyond standard ProGuard ## Observations 1. `JAVA_TOOL_OPTIONS=-Xmx8g` is confirmed picked up when running the JAR directly (`Picked up JAVA_TOOL_OPTIONS: -Xmx8g`), but the OOM persists through REA's MCP layer — suggests the subprocess env isn't inheriting the parent's env vars, or the JAR itself caps heap internally. 2. The JAR manifest has no JVM flags (`Main-Class: com.atxx.jhmcp.MainKt`, nothing else). 3. Same failure on 8GB explicit heap with 32GB system RAM — the APK genuinely needs more than JADX's default allocation, and there's no documented way to control heap for the JADX subprocess spawned by REA. ## Expected Either: - REA propagates `JAVA_TOOL_OPTIONS` / `_JAVA_OPTIONS` to the JADX subprocess - A `REA_JADX_JAVA_OPTS` env var for explicit control - Graceful degradation: partial-load or per-dex analysis instead of loading all 11 dex files at once Large multidex APKs are common in production (banking, logistics, super-apps). A reverse engineering tool that can't open them is limited to demos and CTFs.
Author
Owner

@kaoru0822-kitauji commented on GitHub (Oct 7, 2026):

Addressed on main by #908, after 4.1.0:

  • JVM options pass through: the JADX JVM now inherits the server's environment, including JAVA_TOOL_OPTIONS, JDK_JAVA_OPTIONS, and _JAVA_OPTIONS, and REA does not replace them.
  • Explicit heap control: REA_JADX_HEAP_MIB=8192 adds -Xmx8192m. REA_JADX_ACTIVE_PROCESSOR_COUNT is optional.
  • Lower memory use: class search and inventory read class metadata through a packaged bridge without generating application source, and the loaded APK session is reused across requests.
  • Confirmable heap: Evidence reports the worker's observed Runtime.maxMemory(), so you can confirm which heap actually applied.

See Android analysis. This is a breaking change: the bridge now needs a full JDK 17+ that includes its compiler module.

This was not re-tested against a 133 MB, 11-dex APK. If the next release (release PR #771) still runs out of memory with REA_JADX_HEAP_MIB set, please reopen with the reported maxMemory value.

<!-- gh-comment-id:6041910455 --> @kaoru0822-kitauji commented on GitHub (Oct 7, 2026): Addressed on `main` by #908, after 4.1.0: - **JVM options pass through:** the JADX JVM now inherits the server's environment, including `JAVA_TOOL_OPTIONS`, `JDK_JAVA_OPTIONS`, and `_JAVA_OPTIONS`, and REA does not replace them. - **Explicit heap control:** `REA_JADX_HEAP_MIB=8192` adds `-Xmx8192m`. `REA_JADX_ACTIVE_PROCESSOR_COUNT` is optional. - **Lower memory use:** class search and inventory read class metadata through a packaged bridge without generating application source, and the loaded APK session is reused across requests. - **Confirmable heap:** Evidence reports the worker's observed `Runtime.maxMemory()`, so you can confirm which heap actually applied. See [Android analysis](https://github.com/morluto/rea/blob/main/docs/android-analysis.md). This is a breaking change: the bridge now needs a full JDK 17+ that includes its compiler module. This was not re-tested against a 133 MB, 11-dex APK. If the next release (release PR #771) still runs out of memory with `REA_JADX_HEAP_MIB` set, please reopen with the reported `maxMemory` value.
Author
Owner

@MG1937 commented on GitHub (Oct 12, 2026):

Addressed on main by #908, after 4.1.0:

  • JVM options pass through: the JADX JVM now inherits the server's environment, including JAVA_TOOL_OPTIONS, JDK_JAVA_OPTIONS, and _JAVA_OPTIONS, and REA does not replace them.
  • Explicit heap control: REA_JADX_HEAP_MIB=8192 adds -Xmx8192m. REA_JADX_ACTIVE_PROCESSOR_COUNT is optional.
  • Lower memory use: class search and inventory read class metadata through a packaged bridge without generating application source, and the loaded APK session is reused across requests.
  • Confirmable heap: Evidence reports the worker's observed Runtime.maxMemory(), so you can confirm which heap actually applied.

See Android analysis. This is a breaking change: the bridge now needs a full JDK 17+ that includes its compiler module.

This was not re-tested against a 133 MB, 11-dex APK. If the next release (release PR #771) still runs out of memory with REA_JADX_HEAP_MIB set, please reopen with the reported maxMemory value.

Hello author, could you please add support for this? The JVM memory is often maxed out, and it's truly painful and almost unusable...
https://github.com/morluto/rea/issues/1451#issue-5788603017

作者你好,能适配一下这个吗,jvm内存时常占满,确实很痛苦几乎没法使用...
https://github.com/morluto/rea/issues/1451#issue-5788603017

<!-- gh-comment-id:6128271042 --> @MG1937 commented on GitHub (Oct 12, 2026): > Addressed on `main` by [#908](https://github.com/morluto/rea/pull/908), after 4.1.0: > > * **JVM options pass through:** the JADX JVM now inherits the server's environment, including `JAVA_TOOL_OPTIONS`, `JDK_JAVA_OPTIONS`, and `_JAVA_OPTIONS`, and REA does not replace them. > * **Explicit heap control:** `REA_JADX_HEAP_MIB=8192` adds `-Xmx8192m`. `REA_JADX_ACTIVE_PROCESSOR_COUNT` is optional. > * **Lower memory use:** class search and inventory read class metadata through a packaged bridge without generating application source, and the loaded APK session is reused across requests. > * **Confirmable heap:** Evidence reports the worker's observed `Runtime.maxMemory()`, so you can confirm which heap actually applied. > > See [Android analysis](https://github.com/morluto/rea/blob/main/docs/android-analysis.md). This is a breaking change: the bridge now needs a full JDK 17+ that includes its compiler module. > > This was not re-tested against a 133 MB, 11-dex APK. If the next release (release PR [#771](https://github.com/morluto/rea/pull/771)) still runs out of memory with `REA_JADX_HEAP_MIB` set, please reopen with the reported `maxMemory` value. Hello author, could you please add support for this? The JVM memory is often maxed out, and it's truly painful and almost unusable... https://github.com/morluto/rea/issues/1451#issue-5788603017 作者你好,能适配一下这个吗,jvm内存时常占满,确实很痛苦几乎没法使用... https://github.com/morluto/rea/issues/1451#issue-5788603017
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#361
No description provided.