|
| 1 | +# JRE Bundling Prototype Results |
| 2 | + |
| 3 | +## Status: ✅ SUCCESS |
| 4 | + |
| 5 | +This document tracks the results of the JRE bundling prototype. |
| 6 | + |
| 7 | +## Objective |
| 8 | + |
| 9 | +Create a minimal JRE bundled with the Python package to eliminate external Java dependency. |
| 10 | + |
| 11 | +## Approach |
| 12 | + |
| 13 | +Using Docker for reproducible builds: |
| 14 | +1. Analyze ArcadeDB JAR dependencies |
| 15 | +2. Build minimal JRE with jlink |
| 16 | +3. Package everything into a wheel |
| 17 | + |
| 18 | +## Results |
| 19 | + |
| 20 | +### ✅ Successful Implementation |
| 21 | + |
| 22 | +**Build System:** |
| 23 | +- Docker multi-stage build with Eclipse Temurin JDK 21 |
| 24 | +- Fully reproducible, no host dependencies |
| 25 | +- Automated extraction and packaging workflow |
| 26 | + |
| 27 | +**JRE Specifications:** |
| 28 | +- Size: **63MB** (with zip-9 compression) |
| 29 | +- Java Version: OpenJDK 21.0.8 LTS (Temurin) |
| 30 | +- Modules: 21 Java platform modules |
| 31 | + - Core: `java.base`, `java.compiler`, `java.logging`, `java.management` |
| 32 | + - Database: `java.sql`, `java.transaction.xa`, `java.naming` |
| 33 | + - Security: `java.security.jgss`, `java.security.sasl` |
| 34 | + - Utilities: `java.xml`, `java.rmi`, `java.scripting`, `java.prefs` |
| 35 | + - UI: `java.desktop` (for AWT/font support) |
| 36 | + - JDK: `jdk.jfr`, `jdk.management`, `jdk.sctp`, `jdk.unsupported`, `jdk.incubator.vector`, `jdk.internal.vm.ci` |
| 37 | + - **Critical:** `jdk.zipfs` (required for JPype JAR filesystem access) |
| 38 | + |
| 39 | +**Package Specifications:** |
| 40 | +- Wheel Size: **162MB** total |
| 41 | + - JRE: 63MB |
| 42 | + - JARs: 99MB (85 JARs, gRPC excluded) |
| 43 | + - Python code: <1MB |
| 44 | +- Package Name: `arcadedb_embedded_jre_prototype` |
| 45 | +- Version: 25.10.1-SNAPSHOT (auto-detected from pom.xml) |
| 46 | + |
| 47 | +**Test Results:** |
| 48 | +``` |
| 49 | +✅ Bundled JRE detected correctly (62.2 MB installed) |
| 50 | +✅ Database created successfully |
| 51 | +✅ Transaction committed |
| 52 | +✅ Query executed: bundled_jre_test = 42 |
| 53 | +✅ Package works without system Java! |
| 54 | +``` |
| 55 | + |
| 56 | +### Technical Implementation |
| 57 | + |
| 58 | +**Bundled JRE Detection (`jvm.py`):** |
| 59 | +```python |
| 60 | +def get_bundled_jre_path() -> str | None: |
| 61 | + """Detect if a JRE is bundled with the package.""" |
| 62 | + package_dir = Path(__file__).parent |
| 63 | + jre_dir = package_dir / "jre" |
| 64 | + java_executable = jre_dir / "bin" / "java" |
| 65 | + if java_executable.exists(): |
| 66 | + return str(java_executable) |
| 67 | + return None |
| 68 | +``` |
| 69 | + |
| 70 | +**JPype Integration:** |
| 71 | +- Automatically detects bundled JRE at `arcadedb_embedded/jre/` |
| 72 | +- Uses `libjvm.so` from `jre/lib/server/` for JPype startup |
| 73 | +- Falls back to system Java if bundled JRE not found |
| 74 | +- No code changes required in user applications |
| 75 | + |
| 76 | +**Build Process:** |
| 77 | +1. `build-jre-prototype.sh` - Builds JRE with Docker, extracts results |
| 78 | +2. `test-jre-wheel.sh` - Creates wheel, installs in venv, runs tests |
| 79 | +3. Fully automated, single command: `./build-jre-prototype.sh && ./test-jre-wheel.sh` |
| 80 | + |
| 81 | +### Key Learnings |
| 82 | + |
| 83 | +**Module Requirements:** |
| 84 | +- Initially missing `jdk.zipfs` caused JPype to fail with "Unable to find filesystem for jar" |
| 85 | +- JPype requires JAR filesystem support to access Java modules |
| 86 | +- All AWT/Desktop modules needed even for headless operation (ArcadeDB dependencies) |
| 87 | + |
| 88 | +**Version Management:** |
| 89 | +- `_version.py` must be generated before wheel build |
| 90 | +- Using `write_version.py` from parent directory works correctly |
| 91 | +- Version auto-detected from Maven `pom.xml` |
| 92 | + |
| 93 | +**JVM Startup:** |
| 94 | +- Must pass explicit `libjvm.so` path to JPype |
| 95 | +- Path: `jre/lib/server/libjvm.so` (relative to package root) |
| 96 | +- Cannot rely on JPype's default Java detection when bundling |
| 97 | + |
| 98 | +### File Sizes Comparison |
| 99 | + |
| 100 | +| Component | Size | Notes | |
| 101 | +|-----------|------|-------| |
| 102 | +| Minimal JRE (Docker) | 63MB | jlink with zip-9 compression | |
| 103 | +| JRE (installed) | 62.2MB | Extracted in site-packages | |
| 104 | +| All JARs | 99MB | 85 JARs excluding gRPC | |
| 105 | +| **Total Wheel** | **162MB** | Complete self-contained package | |
| 106 | +| Base Package (no JRE) | ~100MB | For comparison | |
| 107 | + |
| 108 | +### Next Steps |
| 109 | + |
| 110 | +1. **Integration into Main Build:** |
| 111 | + - Add JRE variant to `build-all.sh` |
| 112 | + - Create separate `pyproject.toml` for JRE variant |
| 113 | + - Update GitHub Actions workflow |
| 114 | + |
| 115 | +2. **Package Variants:** |
| 116 | + - `arcadedb-embedded` - Base package (requires system Java) |
| 117 | + - `arcadedb-embedded-jre` - JRE bundled variant (162MB) |
| 118 | + |
| 119 | +3. **Documentation:** |
| 120 | + - Update README with installation options |
| 121 | + - Document JRE bundle for users without Java |
| 122 | + - Add troubleshooting guide |
| 123 | + |
| 124 | +4. **Optimization Opportunities:** |
| 125 | + - Profile which Java modules are actually used at runtime |
| 126 | + - Consider platform-specific wheels (currently linux-x86_64 only) |
| 127 | + - Evaluate GraalVM native-image for even smaller size |
| 128 | + |
| 129 | +### Conclusion |
| 130 | + |
| 131 | +**The JRE bundling prototype is fully functional and ready for integration.** |
| 132 | + |
| 133 | +- Zero external dependencies (no Java installation required) |
| 134 | +- Reasonable size increase (62MB for complete Java independence) |
| 135 | +- Fully automated Docker-based build |
| 136 | +- Production-ready implementation |
0 commit comments