|
| 1 | +# StreamFLOW — Java desktop UI (Phase 0) |
| 2 | + |
| 3 | +Native JavaFX desktop front-end for the StreamFLOW flow-cytometry suite. The |
| 4 | +heavy compute stays in R (Bioconductor / CytoExploreR) running as a background |
| 5 | +process; Java owns the window, file dialogs, and async orchestration. See |
| 6 | +`../engine/streamflow_engine.R` for the R side and the project plan for the full |
| 7 | +architecture. |
| 8 | + |
| 9 | +This is **Phase 0**: the JavaFX ⇄ R bridge, the async job model, the app shell, |
| 10 | +and a developer console that proves the architecture end-to-end. The real |
| 11 | +analysis modules land in later phases. |
| 12 | + |
| 13 | +## Prerequisites |
| 14 | + |
| 15 | +The repo is **self-contained for building** — no system JDK or Maven needed: |
| 16 | + |
| 17 | +- **JDK**: bundled **Microsoft Build of OpenJDK 25 (LTS)** at `../jdk-25.0.3+9`. |
| 18 | +- **Maven**: bundled **Apache Maven 3.9.16** at `../apache-maven-3.9.16`. |
| 19 | +- The `build.ps1` / `run-dev.ps1` scripts pin `JAVA_HOME`, use the bundled Maven, |
| 20 | + and set `MAVEN_OPTS` to trust the **Windows certificate store** (so Maven Central |
| 21 | + works behind a TLS-intercepting proxy/AV — otherwise you'd get a PKIX |
| 22 | + "unable to find valid certification path" error). |
| 23 | +- **R** is the only external requirement: `jsonlite` for Phase 0, and from Phase 1 |
| 24 | + on the full Bioconductor/CytoExploreR stack. In a packaged build this is the |
| 25 | + bundled `R-Portable`; in dev, point the scripts at any Rscript with `-Rscript`. |
| 26 | + |
| 27 | +> The repo lives in a OneDrive-synced folder, which can transiently lock |
| 28 | +> `target/`; if `mvn clean` fails to delete it, just `rm -rf target` and retry. |
| 29 | +
|
| 30 | +## Run the app (dev) |
| 31 | + |
| 32 | +```powershell |
| 33 | +# from app\ |
| 34 | +./run-dev.ps1 # Rscript from PATH / bundled R-Portable |
| 35 | +./run-dev.ps1 -Rscript "C:\Program Files\R\R-4.4.2\bin\Rscript.exe" |
| 36 | +``` |
| 37 | + |
| 38 | +Then in the **Developer / Engine Console**: |
| 39 | +- **Ping / R Version** — basic round-trip over the stdio JSON protocol. |
| 40 | +- **Sleep (5s, cancellable)** — start it, then click the nav items and drag the |
| 41 | + window: the UI stays fully responsive while R works (the freeze fix). Hit |
| 42 | + **Cancel** to prove cooperative cancellation. |
| 43 | +- **Trigger Error** — shows the real R error message surfaced to the UI. |
| 44 | +- **Noisy stdout** — R does `cat()`/`print()`; the JSON stream stays intact |
| 45 | + (proves the `sink(stderr())` guard). |
| 46 | + |
| 47 | +## Verify (Phase 0 gate) |
| 48 | + |
| 49 | +```powershell |
| 50 | +# from app\ — runs the protocol conformance test against a real R engine |
| 51 | +./build.ps1 -Rscript "C:\Program Files\R\R-4.4.2\bin\Rscript.exe" |
| 52 | +``` |
| 53 | + |
| 54 | +`ProtocolConformanceTest` asserts: ready handshake, echo/version round-trip, |
| 55 | +progress frames, cooperative cancel, error+traceback replies, malformed-request |
| 56 | +resilience, and that stray R stdout never corrupts the stream. (The test is |
| 57 | +skipped automatically if no Rscript is available.) |
| 58 | + |
| 59 | +Orphan-safety check (manual): launch the app, find the child `Rscript.exe` in |
| 60 | +Task Manager, kill the `java`/JavaFX process — the engine should exit on its own |
| 61 | +within seconds (stdin EOF), leaving no lingering R process. |
| 62 | + |
| 63 | +## Build a Windows app (jpackage) |
| 64 | + |
| 65 | +Produces a self-contained app-image (StreamFLOW.exe + bundled JRE + R), so end |
| 66 | +users need neither Java nor R: |
| 67 | + |
| 68 | +```powershell |
| 69 | +# 1) one-time / when R deps change — stage a minimal portable R (slow, ~1 GB): |
| 70 | +powershell -ExecutionPolicy Bypass -File engine\stage-r-portable.ps1 |
| 71 | +# 2) build the app image (or add -Installer for an .exe, needs WiX): |
| 72 | +powershell -ExecutionPolicy Bypass -File app\package.ps1 |
| 73 | +# output: app\target\dist\StreamFLOW\ |
| 74 | +``` |
| 75 | + |
| 76 | +The app resolves the bundled engine + R-Portable via `-Dstreamflow.appDir` |
| 77 | +(set by `package.ps1`). *Status: scripts are ready; the first packaged build still |
| 78 | +needs a validation run (jpackage classpath + runtime path).* |
| 79 | + |
| 80 | +## Layout |
| 81 | + |
| 82 | +``` |
| 83 | +app/ |
| 84 | + pom.xml Maven build (OpenJFX, controlsfx, Jackson, JUnit) |
| 85 | + run-dev.ps1 / build.ps1 JDK-pinned launchers |
| 86 | + src/main/java/org/streamflow/ |
| 87 | + StreamFlowApp.java JavaFX entry point |
| 88 | + bridge/ R process + stdio JSON protocol + async jobs |
| 89 | + ui/MainController.java shell controller (Phase 0 dev console) |
| 90 | + src/main/resources/org/streamflow/ui/ |
| 91 | + main.fxml, streamflow-dark.css |
| 92 | + src/test/java/.../ProtocolConformanceTest.java |
| 93 | +``` |
0 commit comments