GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Migrate many SciJava Common subsystems by ctrueden · Pull Request #295 · scijava/scijava

Migrate many SciJava Common subsystems #295

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Sign up for GitHub

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
ctrueden wants to merge 59 commits into main
base: main
Loading
Loading
from scijava-common-migration

Uh oh!

There was an error while loading. Please reload this page.

Open

Migrate many SciJava Common subsystems #295

Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
5e9836a
docs: add SciJava Common migration plan
ctrueden Sep 16, 2026
82cd7c8
scijava-ops-image: stop using SciJava Common utilities
ctrueden Sep 16, 2026
71852f7
scijava-discovery: make Discoverer yield lazy descriptors
ctrueden Sep 16, 2026
0771222
Pin scijava-discovery and scijava-priority versions
ctrueden Sep 16, 2026
4b8feff
Pin every consumed SciJava artifact version
ctrueden Sep 16, 2026
9084574
scijava-spi: add a module of framework-free interfaces
ctrueden Sep 16, 2026
9a5b15e
scijava-common3: absorb general utilities from SciJava Common
ctrueden Sep 16, 2026
24ba06b
scijava-common3: add FilePaths, from SciJava Common's FileUtils
ctrueden Sep 16, 2026
7d73482
scijava-index: port annotation indexing, with a lazy Discoverer
ctrueden Sep 16, 2026
313843f
docs: correct the Phase 2 injection design
ctrueden Sep 16, 2026
790ec74
scijava-io3: port locations, standalone on plain ServiceLoader
ctrueden Sep 16, 2026
c7842b0
scijava-io3: port data handles
ctrueden Sep 16, 2026
ea1ac3c
Make cancellation thread interruption
ctrueden Sep 16, 2026
ef68624
scijava-concurrent: let cancellation survive a parallel section
ctrueden Sep 16, 2026
df12101
docs: do not port io.nio
ctrueden Sep 16, 2026
80f4333
scijava-io3: port ByteBufferByteBank, keeping direct banks off-heap
ctrueden Sep 16, 2026
5039837
scijava-events: a typed event bus, written clean
ctrueden Sep 16, 2026
e09d280
docs: record incarnational versioning, and defer scijava-persist
ctrueden Sep 17, 2026
f65c690
scijava-io3: start at 3.0.0-SNAPSHOT
ctrueden Sep 17, 2026
caa9640
scijava-context: the container core
ctrueden Sep 17, 2026
7822074
scijava-context: the plugin tier
ctrueden Sep 17, 2026
394b956
scijava-context: declarative dependency injection
ctrueden Sep 17, 2026
de2e89f
scijava-context: @EventHandler scanning
ctrueden Sep 17, 2026
2e01213
docs: scrutinize the core services, and settle the preferences design
ctrueden Sep 17, 2026
9156ef6
docs: use TOML rather than YAML for the settings store
ctrueden Sep 17, 2026
634d940
scijava-execute: run things that declare their inputs and outputs
ctrueden Sep 17, 2026
1e1e662
scijava-execute: the pre/postprocessor chain
ctrueden Sep 17, 2026
95b4e57
docs: say how Fiji gets built on SciJava3
ctrueden Sep 17, 2026
0138735
scijava-execute: generalize beyond Java classes, for scripts
ctrueden Sep 17, 2026
0e4ac38
scijava-command: discoverable commands, and the metadata menus need
ctrueden Sep 17, 2026
80bab69
One opens, to the container
ctrueden Sep 17, 2026
cfead6d
Add the menu tree, and make Access a static utility
ctrueden Sep 17, 2026
b6ff554
scijava-harvest: prototype the parameter dialog model
ctrueden Sep 17, 2026
df48f01
Support computed parameter choices, closing the DynamicCommand gap
ctrueden Sep 17, 2026
58fd161
scijava-ui3 and scijava-swing: widgets, and dialogs to click on
ctrueden Sep 17, 2026
0a57e16
Fix the widget bugs the demos turned up, and fill in the gaps
ctrueden Sep 17, 2026
1384996
Ignore Eclipse's .factorypath
ctrueden Sep 17, 2026
46a5f3e
migration.md: the command row was ported two commits ago
ctrueden Sep 17, 2026
193a373
A Swing shell: menus, search, status -- the first whole-stack demo
ctrueden Sep 18, 2026
19e9d00
scijava-javafx: a second binding, and what it proved
ctrueden Sep 18, 2026
ad4ed60
scijava-awt: a third binding, and where the shared code belongs
ctrueden Sep 18, 2026
ada9894
scijava-convert3: one question, and it sits below the container
ctrueden Sep 18, 2026
22c0dc6
scijava-script3: a script is an Executable like any other
ctrueden Sep 18, 2026
40d687d
Scripts declare their presentation, and menus take more than one source
ctrueden Sep 18, 2026
7c100d4
Name the general thing what users call it: CommandInfo
ctrueden Sep 18, 2026
477a544
The legacy bridge, and the split package it found
ctrueden Sep 18, 2026
1f0084d
One name per foreign library: scijava-compat, -ops-compat, -imagej-co…
ctrueden Sep 18, 2026
1d8efbd
migration.md: say what the presentation metadata actually does
ctrueden Sep 18, 2026
3a2aa7e
scijava-cli: run the same commands without a display
ctrueden Sep 18, 2026
eccf33e
scijava-settings: one TOML file a person can read and edit
ctrueden Sep 19, 2026
7f4e5fa
Shorten submodule folder names
ctrueden Sep 20, 2026
680d702
Make Context.doDispose() less deadlock-prone
ctrueden Sep 25, 2026
a641987
Migrate incarnational versioning writeup to here
ctrueden Oct 26, 2026
e625d35
README: fix build badge
ctrueden Oct 26, 2026
ee70467
Fix wrong suggested scijava-ops-indexer version
ctrueden Oct 26, 2026
a3f8e24
Pin the migration plan's scijava-persist version
ctrueden Oct 26, 2026
289a91c
Fix javadoc errors
ctrueden Oct 26, 2026
e197fad
Make DiscoveryLazinessTest independent of test order
ctrueden Oct 28, 2026
ba91881
Address Copilot review feedback
ctrueden Oct 28, 2026
File filter
Filter by extension

Clear filters
Conversations
Failed to load comments.
Loading

Uh oh!

There was an error while loading. Please reload this page.

Jump to
Jump to file
Failed to load files.
Loading

Uh oh!

There was an error while loading. Please reload this page.

Diff view
Diff view
Prev Previous commit
Next Next commit
docs: say how Fiji gets built on SciJava3
The plan kept saying "drop" about the application shell without saying
where it goes instead, which reads as though Fiji loses its menus. It
does not: the problem with SciJava Common was never that it had menus,
but that the core had them, so a library wanting only plugin discovery
inherited MenuPath, Display and a transitive AWT flavour.

Adds a layering section: foundation (built) / application model /
toolkit bindings / application, with only the bindings importing AWT or
Swing. All of the presentation metadata survives -- menu path, label,
icon, accelerator, weight, selection group, visibility, enablement --
since Fiji's menus are built from it. What changes is that it becomes
attributes in the annotation index rather than the
BasicDetails/UIDetails/AbstractUIDetails inheritance chain every plugin
extends.

Notes that the expensive part is already solved: SciJava Common builds
its menu from ModuleInfo, naming classes without loading them and
loading on demand, which is exactly the implClassName()/type()/get()
split of Discovery. The other seams -- harvesting as a Preprocessor,
displays as a Postprocessor, input events with Consumable -- were built
in phases 1-3 with this in mind.

Also records that the real risk is migration rather than architecture:
hundreds of commands across dozens of repositories cannot update on a
flag day, so the one-way legacy bridge matters more than its deferral
implies and should be sequenced with layer 1 rather than after it.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_013gJpzGd3ksbME4CN6Tu2ni
  • Loading branch information

Uh oh!

There was an error while loading. Please reload this page.

@ctrueden @claude
ctrueden and claude committed Oct 28, 2026
commit 95b4e5706632070a06e7484fc80ec967a420ff65

There are no files selected for viewing

92 changes: 89 additions & 3 deletions 92 docs/migration-plan.md
Show comments
View file
Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,90 @@ No application context required by anything in this phase.
`#@` parameters parse into structs. The external `scripting-*` repositories
migrate onto the facade.

## Layering: how Fiji gets built on SJ3

The problem with SciJava Common was never that it had menus. It is that the
*core* had them: one artifact bundles the plugin framework, the application
container, menus, displays, tools and a UI opinion, so a library wanting only
plugin discovery inherits `MenuPath`, `Display` and a transitive AWT flavour.

The remedy is **stratification, not deletion**. Everything Fiji needs still
exists; it moves to a layer that can be depended on separately. Where this
document says a subsystem is "dropped", that means *dropped from the core* —
unless it says there is no replacement at all, which it says explicitly.

| Layer | Contents | Depends on |
| --- | --- | --- |
| **0. Foundation** (built) | `spi`, `common3`, `collections`, `priority`, `progress`, `concurrent`, `discovery`, `index`, `struct`, `io3`, `events`, `context`, `execute` | nothing above |
| **1. Application model** (to build) | `scijava-command` (a struct plus presentation metadata), `scijava-menu` (the menu tree), `scijava-ui-api` (toolkit-agnostic contracts), `scijava-desktop` | layer 0 |
| **2. Toolkit bindings** | `scijava-ui-swing`, JavaFX, headless | layer 1 |
| **3. Application** | Fiji: which menus exist, branding, update sites, defaults | layer 2 |

Only layer 2 imports AWT or Swing. Layer 0 never mentions a user interface, so
headless is not a mode — it is what the core does.

### The mechanisms are already in place

The machinery the application shell needs was built in phases 1-3, and in
several cases was built *because* of it:

| Fiji needs | Built |
| --- | --- |
| Menus over hundreds of commands, without loading their classes | the `@Plugin` index, and `Discovery.implClassName()`/`attrs()` before `type()`/`get()` |
| Parameter dialogs | `Preprocessor`: harvesting is a preprocessing step |
| "The user pressed Cancel" | `Execution.decline(reason)`, reported by `ExecutionResult` |
| Showing outputs | `Postprocessor`: the `DisplayPostprocessor` seam |
| Tool and input events, one handler claiming a keystroke | `scijava-events`, with `Consumable` |
| Menu ordering | `scijava-priority`, plus a weight attribute in the index |

NB: SciJava Common builds its menu from `ModuleInfo`, whose
`getDelegateClassName()` names the class without loading it and whose
`loadDelegateClass()` loads on demand. That is exactly the
`implClassName()`/`type()`/`get()` split of `Discovery`, so the expensive part
of the menu story is already solved and tested.

### What changes, and what does not

**All of the presentation metadata survives** — menu path, label, icon,
accelerator, weight, selection group, visibility, enablement. Fiji's menus are
built from it, and hundreds of commands depend on it.

**It becomes data rather than an inheritance chain.** SciJava Common has
`BasicDetails` → `UIDetails` → `AbstractUIDetails`, which every plugin extends
in order to carry a label. Here it is attributes in the annotation index, read
without loading, with a command-info view over `Discovery`. The same
information, fewer types, a faster menu build. Expect commands to look like:

```java
@Command(menuPath = "Image>Adjust>Brightness/Contrast...", weight = 12,
accelerator = "^C", iconPath = "/icons/bc.png")
public class BrightnessContrast implements Runnable {
@Parameter private Dataset image;
}
```

`@Command` as its own `@Indexable` annotation: `IndexDiscoverer` is generic
over the annotation type, so a dedicated, self-documenting annotation costs
nothing compared with stuffing this into `@Plugin` attributes.

**Reworked rather than ported:** `AbstractUIDetails`'s inheritance, the
`display` package's `DisplayService`/`Display`/`DisplayViewer`/`DisplayPanel`
layering, and the `Gateway`/`SciJava` convenience object. Those are shape
problems; the capabilities survive.

### The real risk is migration, not architecture

Hundreds of commands live across dozens of repositories with different
maintainers. Per command the change is mechanical, but there is no flag day on
which they all update.

So the **one-way legacy bridge matters more than its deferral implies**: for
Fiji to run on SJ3 before every command is ported, an SJ3 application must
present SciJava Common `ModuleInfo`s as SJ3 commands — metadata flowing both
ways, dependency flowing one way. That is what makes the migration incremental
rather than a big bang, and it should be sequenced *with* layer 1 rather than
after it.

### Phase 4 — UI and desktop

- **Input harvesting is a headline deliverable**, not a port. It is the
Expand All @@ -684,8 +768,10 @@ No application context required by anything in this phase.
and the prototype preserved on the `historical/scijava-ops-prototype` branch
(`widget/`, `swing-widget/`), which is the design starting point rather than
`org.scijava.widget` as written.
- **Drop** the opinionated application shell: `ApplicationFrame`, `Desktop`,
`StatusBar`, `ToolBar`. The SJ3 UI API is minimal.
- **The application shell moves to layers 1 and 2**, it is not discarded:
`ApplicationFrame`, `Desktop`, `StatusBar` and `ToolBar` are contracts in
`scijava-ui-api` and implementations in the toolkit bindings. What the core
drops is any knowledge that they exist.
- **`input` and `tool`** are re-framed, not frozen: UI-agnostic facades over
GUI concepts, layered on `scijava-events`, letting code listen for GUI
events or implement interactive behavior (e.g. a pencil tool) without
Expand Down Expand Up @@ -718,7 +804,7 @@ No application context required by anything in this phase.
| `module`, `command` | → execution layer (Phase 3) |
| `script` | → scripting facade + adapters (Phase 3) |
| `widget` | → input harvesting, redesigned (Phase 4) |
| `ui`, `menu` | Minimal UI API; app shell dropped (Phase 4) |
| `ui`, `menu` | `scijava-ui-api` contracts and `scijava-menu` (layer 1), with toolkit bindings in layer 2 (Phase 4) |
| `input`, `tool` | Re-framed as UI-agnostic facades (Phase 4) |
| `display` | Overhauled, not ported (Phase 4) |
| `platform`, `ui.dnd` | `scijava-desktop` modernization (Phase 4) |
Expand Down
4 changes: 2 additions & 2 deletions 4 docs/migration.md
Show comments
View file
Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ A **dropped** row is a successful outcome, not a gap.
| `Contextual`, `AbstractContextual`, `NullContextException` | dropped — a service receives its context in `Service.initialize(Context)`, so it need not carry one, and there is no null-context state to report | dropped |
| `Gateway`, `AbstractGateway`, `SciJava` | Phase 2, if retained at all | open |
| `Instantiable`, `InstantiableException` | subsumed by `Discovery` | planned |
| `BasicDetails`, `AbstractBasicDetails`, `UIDetails`, `AbstractUIDetails`, `MenuEntry`, `MenuPath` | plugin/module metadata (Phases 2–4) | open |
| `BasicDetails`, `AbstractBasicDetails`, `UIDetails`, `AbstractUIDetails`, `MenuEntry`, `MenuPath` | `scijava-command` presentation metadata (layer 1). All of it survives — menu path, label, icon, accelerator, weight, selection group, visibility, enablement — but as attributes in the annotation index rather than an inheritance chain every plugin extends | planned |
| `Validated`, `ValidityProblem` | execution layer (Phase 3) | open |
| `Optional` | `scijava-optional` (satellite repo, moves in later) | open |

Expand Down Expand Up @@ -125,7 +125,7 @@ A **dropped** row is a successful outcome, not a gap.
| `command` | still to come: a command is a struct plus menu metadata plus `run` | planned |
| `script`, `script.process` | scripting facade + `javax.script` / GraalVM polyglot / Appose adapters (Phase 3) | planned |
| `widget` | input harvesting on `scijava-struct`, with dynamic subgroups (Phase 4) | planned |
| `ui`, `menu` | minimal UI API; `ApplicationFrame`/`Desktop`/`StatusBar`/`ToolBar` dropped (Phase 4) | planned |
| `ui`, `menu` | `scijava-ui-api` (toolkit-agnostic contracts) and `scijava-menu` (the menu tree), with `ApplicationFrame`/`Desktop`/`StatusBar`/`ToolBar` as contracts there and implementations in the toolkit bindings. Dropped from the *core*, not from the stack — see the layering section of [migration-plan.md](migration-plan.md) | planned |
| `input`, `tool` | UI-agnostic facades on `scijava-events` (Phase 4) | planned |
| `display` | overhauled, not ported (Phase 4) | open |
| `platform`, `ui.dnd` | `scijava-desktop` modernization (Phase 4) | planned |
Expand Down
Add this suggestion to a batch that can be applied as a single commit. This suggestion is invalid because no changes were made to the code. Suggestions cannot be applied while the pull request is closed. Suggestions cannot be applied while viewing a subset of changes. Only one suggestion per line can be applied in a batch. Add this suggestion to a batch that can be applied as a single commit. Applying suggestions on deleted lines is not supported. You must change the existing code in this line in order to create a valid suggestion. Outdated suggestions cannot be applied. This suggestion has been applied or marked resolved. Suggestions cannot be applied from pending reviews. Suggestions cannot be applied on multi-line comments. Suggestions cannot be applied while the pull request is queued to merge. Suggestion cannot be applied right now. Please check back later.
You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.