chris.giteaandClaude Opus 5.5 572016c5e0 build: drop unused libraries from the executable jar
The repackaged jar no longer ships the OpenJFX jars (every target runtime
provides JavaFX as modules, and they only held the build machine's
natives), Jilt (compile-time annotations, like Lombok) or the JUnit 6 and
AssertJ that devtoolsfx-connector wrongly declares at compile scope:
107 -> 89 libraries, 236.5 -> 223.4 MB. The POM version is reset to 0.0.1.

The README documents what takes space in the jar, and that the desktop
interface needs --ui.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011xpLSeYKKHX6o16jzYLgZv
2026-09-30 14:12:55 -04:00
2026-08-22 17:52:02 -04:00
2026-08-22 11:54:20 -04:00
2026-08-22 11:54:20 -04:00
2026-08-08 23:21:21 -04:00
2026-07-26 18:49:07 -04:00
2026-07-26 18:49:07 -04:00

Pholio

Pholio is a desktop application for managing large photo and video libraries, built for volume and speed.

  • Libraries — point Pholio at one or more folders; it indexes every photo and video into its own embedded database, one per library, and keeps it in sync as files change.
  • Gallery — a justified, date-grouped grid that stays fluid on tens of thousands of files, with a full-screen photo view and an info panel for the selected file.
  • Metadata — reads EXIF, IPTC and XMP (RAW, HEIF and video included), edits capture date, location and rating, and writes them back to the file itself.
  • Places — offline reverse geocoding from a bundled GeoNames dataset, plus optional online place search (LocationIQ).
  • People — local face and animal detection and clustering (ONNX Runtime, nothing leaves the machine); naming a person makes their photos searchable.
  • Search — free text, rating (r:4+), people (p:Alice) and folder (path:Holidays/2024) filters, combined freely — see the in-app guide (the ? next to the search bar) or src/main/resources/userguide.
  • Command line — the same binary runs headless: pholio scan <dir> reports the media files a folder holds.

Built with Java 26, JavaFX (AtlantaFX, GemsFX, Ikonli), Spring Boot, H2, PicoCLI and metadata-extractor.

Build and run

Requirements: a JDK 26 that bundles JavaFX (e.g. Azul Zulu FX 26). Maven comes with the wrapper.

./mvnw verify                      # compile, test, build target/pholio.jar
java -jar target/pholio.jar --ui   # desktop interface
java -jar target/pholio.jar scan ~/Pictures [-R]   # headless scan; -R: do not recurse
java -jar target/pholio.jar -V     # version
java -jar target/pholio.jar        # usage, same as --help

Pholio runs headless by default: only --ui opens the window, so every launcher meant to show one (IDE run configuration, installers) passes it. Any argument Pholio does not recognise is read as a command.

Development

JVM options (-D…)

Option Default Effect
--enable-native-access=javafx.graphics,ALL-UNNAMED — Not a property, but recommended: silences the restricted-method warnings from JavaFX, JNA and the macOS process naming.
-Dpholio.home=<dir> OS user dirs Puts configuration, data (libraries) and cache under one root — keeps a test run out of your real profile.
-Dpholio.skipTheme=true false Starts without the AtlantaFX theme, on JavaFX's default styling (to tell a theme issue from a layout one).
-Dpholio.modalBackend=dialogPane stage Shows dialogs in GemsFX's embedded DialogPane instead of a separate window.
-Djavafx.enablePreview=true set by the app Required for the JavaFX HeaderBar preview API; GuiBootstrap sets it unless you pass a value.
-Dprism.dirtyopts=false set by the app Works around a stale-paint bug in Prism; GuiBootstrap sets it unless you pass a value.

Application settings (--pholio.…= arguments)

Spring Boot settings from application.yaml, overridable on the command line (they bypass PicoCLI, so they never read as a command):

Setting Default Effect
--pholio.dev-tools.enabled= true F12 opens the DevToolsFX scene-graph inspector.
--pholio.library.routing.enabled= true Routes the database to the library picked in the header; false pins spring.datasource.url.
--pholio.pools.cpu= 0 Threads for decoding work (thumbnails, hashes); 0 = cores − 1.
--pholio.pools.scheduler= 2 Scheduler threads.
--pholio.window.default-width= / default-height= 1440 / 900 First-run window size.
--logging.level.org.icroco.pholio= DEBUG Log level of Pholio's own code.

What makes the jar big

target/pholio.jar is ~223 MB, 89 libraries. Almost all of it is recognition: the application's own code is under 1 MB.

Size (in the jar) Entry Why
130.5 MB onnxruntime-1.21.1.jar ONNX Runtime with native libraries for 5 platforms (~590 MB unpacked, win-x64 alone 351 MB). The installers keep only their own platform's — see below.
34.2 MB models/recognition/face_recognition_sface_2021dec.onnx Face embedding model (SFace).
10.2 MB geodata/cities1000.txt.gz GeoNames seed for offline reverse geocoding, imported into H2 on first run.
4.4 MB byte-buddy Runtime agent behind @FxThread.
3.2 MB models/recognition/yolox_nano.onnx Animal detection model.
3.0 MB gemsfx UI controls.
2.6 MB h2 Embedded database.
≤ 2 MB each Spring, Jackson, JNA, AtlantaFX themes, … The remaining ~30 MB.

Deliberately left out of the jar (pom.xml): Lombok and Jilt (compile-time only), the OpenJFX jars (every target runtime already has JavaFX as modules), and the JUnit/AssertJ that devtoolsfx wrongly declares at compile scope.

The native installers go further (distrib/packaging/common.sh): only the target platform's ONNX Runtime natives (130 MB → ~24 MB for macOS arm64) and a jlink'ed runtime (~64 MB) — the macOS arm64 .dmg is ~157 MB.

To re-measure: unzip -v target/pholio.jar | sort -k3 -n -r | head -20 (third column: compressed size).

Useful scripts

  • python3 tools/icons/make-macos-icon.py — regenerates the macOS icon, icon.png and pholio.icns from src/main/resources/images/spo-1024x1024.png.

Release

./mvnw -Prelease validate

Needs a clean working tree (or -Drelease.allowDirty=true) and a logged-in GitHub CLI (gh auth login). In order, it:

  1. bumps the version to YYYY.M.N — same month as the current version: N + 1, otherwise build 0 of the current month;
  2. runs a fresh ./mvnw verify;
  3. writes distrib/release_note/release-note-<version>.md from the Conventional Commits since the previous release (grouped by type, then scope);
  4. creates GitHub release v<version> in Imag-In/Pholio with the jar, its SHA-256 and the release note;
  5. commits pom.xml and tags v<version> locally;
  6. commits the release note in distrib/ and pushes it.

The source repository itself is never pushed to GitHub: Imag-In/Pholio only receives release assets and the distrib/ worktree (an orphan branch), and a local pre-push hook enforces it. See AGENTS.md for the details, and keep commit messages in the Conventional Commits format so they reach the release note.

S
Description
No description provided
Readme
54 MiB
Languages
Java 97.4%
CSS 1.5%
Python 0.9%
JavaScript 0.2%