Skip to content

[roadmap] 003 — Upgrade Dependencies to Current Versions #3

@oluies

Description

@oluies

Draft planning artifact generated via spec-kit — see specs/003-dependency-upgrades/ (spec, plan, research, data-model, contracts, quickstart, tasks).

⚠️ Unverified draft: authored without a build environment (no Gradle/JDK 17/network/TIBCO/DuckDB). On branch t/yolo-d76fe7 (not yet pushed).

Tasks (mirrors specs/003-dependency-upgrades/tasks.md)

Phase 1: Setup

  • T001 Confirm feature 001 has landed and is the authoritative baseline: gradle/libs.versions.toml, build.gradle.kts, the Java 17 toolchain, GitHub Actions CI, and Dependabot all exist; record the 001-mapped baseline versions (log4j 1.2.15, Guava r08, Guice 2.0, beansbinding 1.2.1, BSAF 1.9, Glazed Lists 1.7.0/glazedlists_java15, jgoodies-forms 1.2.0, commons-cli 1.2, XOM 1.2.6, JUnit 4.4) so every delta is measured from the mapped baseline, not the literal vendored snapshot (plan Complexity "entanglement with 001"; spec Assumptions)
  • T002 [P] Create the upgrade-decision ledger specs/003-dependency-upgrades/upgrade-decisions.md with one row per in-scope library (fields: library, baseline coordinate/version, target, decision, rationale, licence_check, api_delta, risk, verified=no) per data-model.md "Upgrade-decision record" (FR-017; satisfies SC-004's "documented decision" requirement)
  • T003 [P] [ENV:build] Capture a pre-upgrade reference dependency report (./gradlew dependencies) and the current test count + names, to diff against after the bumps (baseline for FR-009/SC-006 conflict checks and FR-010/SC-005 "no test silently dropped")

Phase 2: Foundational (Blocking Prerequisites)

  • T004 [ENV:launch] Guice-on-Java-17 go/no-go spike (R1): in a throwaway branch, bump com.google.inject:guice to the default Guice 5.1.x line in gradle/libs.versions.toml, build, and confirm the object graph wires with no IllegalAccessError/InaccessibleObjectException/bytecode-generation failure; record GO/decision in specs/003-dependency-upgrades/upgrade-decisions.md (CONTRACT-DI-1; FR-002/SC-001) — gates US1
  • T005 [ENV:launch] BSAF-on-Java-17 availability + run spike (R5, edge case): confirm a org.bsaf:bsaf (and org.jdesktop:beansbinding) release that runs on Java 17 exists (VERIFY-AVAIL); launch far enough to exercise the BSAF-driven RvSnoopApplication lifecycle; if none runs, record the documented decision (pin-latest-viable / vendor-patched / replace) in the ledger (CONTRACT-MIG-6; FR-001/FR-017) — gates the US3 BSAF/beansbinding work
  • T006 [ENV:build] Add the single-version resolution scaffolding in build.gradle.kts — a resolutionStrategy.force (or catalog constraints) block for the clash-prone coordinates ASM/cglib, Guava, and SLF4J — and enable a Gradle dependency-conflict report in CI so conflicts are surfaced, never silently picked (research R8; FR-008/FR-009; CONTRACT-DEP-2; CONTRACT-CI-2)
  • T007 Verify gradle/libs.versions.toml leaves the db4o entry byte-identical to feature 001's pin and that no task in this feature references db4o; note this guard in the ledger (research R10; FR-015/SC-008; CONTRACT-DEP-6)

Phase 3: User Story 1 - Run on Java 17 with a supported DI container (Priority: P1) 🎯 MVP

  • T008 [P] [US1] [ENV:build] Run the existing DI-wired tests on Java 17 to confirm the upgraded container wires test-exercised components without error (no new test file needed — reuses the existing suite under src/test/org/rvsnoop/) (CONTRACT-DI-4; FR-011, US1 acceptance [roadmap] 003 — Upgrade Dependencies to Current Versions #3)
  • T009 [US1] Retarget the DI coordinate in gradle/libs.versions.toml: com.google.inject:guice 2.0 → Guice 5.1.x (verify latest 5.x); record target + Apache-2.0 licence check in the decision ledger (research R1; FR-001/FR-016/FR-017)
  • T010 [US1] Rewrite the removed internal Guice API in src/main/org/rvsnoop/matchers/RvSnoopMatcherEditor.java: replace com.google.inject.internal.ToStringBuilder with a public equivalent (com.google.common.base.MoreObjects.toStringHelper, which also advances R3, or a hand-written toString) (research R1; CONTRACT-DI-3; FR-007)
  • T011 [P] [US1] [ENV:build] Recompile the @Inject/Module/Injector call sites against Guice 5.x, fixing any 2.0→5.x API drift while keeping behaviour, in src/main/org/rvsnoop/Application.java, src/main/org/rvsnoop/ui/RvSnoopApplication.java, src/main/org/rvsnoop/ProjectService.java, src/main/org/rvsnoop/Connections.java, src/main/org/rvsnoop/ui/RecordLedgerFormat.java, src/main/rvsnoop/RecordTypes.java (research R1; FR-007) — these import com.google.inject.*/javax.inject, which 5.x preserves
  • T012 [US1] [ENV:build] Run the Gradle dependency report and confirm exactly one ASM/cglib version on the path after the Guice bump (modern Guice relocates its ASM); adjust the T006 force block if a conflict appears (FR-008/FR-009; CONTRACT-DEP-2)
  • T013 [US1] (only if Guice 7.x is selected over the 5.x default) Migrate @Inject/@Singleton/@Named from javax.inject/com.google.inject to jakarta.inject across all sites in T011 (+ RvSnoopMatcherEditor), and confirm no other library still binds javax.inject; record the namespace decision in the ledger (data-model.md "Annotation namespace"; research R1 [CLARIFY]; FR-007)
  • T014 [US1] [ENV:launch] Validate quickstart Scenario 1: object graph constructs with no IllegalAccessError/InaccessibleObjectException/bytecode failure; main window opens, menus respond, connection dialog opens (CONTRACT-DI-1/2; FR-002/FR-003, SC-001)

Phase 4: User Story 2 - No end-of-life or known-vulnerable logging dependency (Priority: P1)

  • T015 [P] [US2] [ENV:build] Add a focused logging test asserting org.rvsnoop.Logger emits at DEBUG/INFO/WARN/ERROR with the levels mapped unchanged onto the new backend, in src/test/org/rvsnoop/LoggerTest.java (no broker required) (CONTRACT-LOG-4; FR-005)
  • T016 [US2] Retarget the logging coordinates in gradle/libs.versions.toml: remove log4j:log4j:1.2.15; add the SLF4J API + Logback backend + Log4j-1.2 bridge (default), OR ch.qos.reload4j:reload4j (alternative) (verify coordinates/versions); record the chosen stack + licence (SLF4J MIT / Logback EPL-or-LGPL — verify Principle I acceptability / reload4j Apache-2.0) in the decision ledger (research R2; FR-004/FR-016/FR-017; CONTRACT-LOG-1)
  • T017 [US2] Migrate the single logging seam src/main/org/rvsnoop/Logger.java from org.apache.log4j.Logger/org.apache.log4j.Level to the SLF4J API, preserving the level mapping and public method behaviour (no-op if reload4j is chosen — the facade keeps the log4j API) (research R2; CONTRACT-LOG-4; FR-005/FR-007)
  • T018 [US2] Migrate the logging configuration src/main/log4j.properties → Logback logback.xml (or Log4j2 config), preserving levels/appenders/targets so operator control is retained (left verbatim if reload4j is chosen) (research R2; FR-005; CONTRACT-LOG-2)
  • T019 [US2] [ENV:build] Ensure the Log4j-1.2 legacy bridge is on the runtime path so third-party libraries calling org.apache.log4j.* are still captured; confirm exactly one SLF4J major resolves (no log4j:log4j:1.2.x, no duplicate SLF4J), adjusting the T006 force block if needed (research R2/R8; FR-006/FR-009; CONTRACT-LOG-3, CONTRACT-DEP-2)
  • T020 [US2] [ENV:launch] Validate quickstart Scenarios 2 + 3: manifest free of EOL/CVE log4j 1.2.x; messages appear at the same levels/destinations; legacy-API output captured with no silent loss (CONTRACT-LOG-1/2/3; FR-004/FR-005/FR-006, SC-002/SC-003)

Phase 5: User Story 3 - All other open-source libraries are current and the app still works (Priority: P2)

  • T021 [P] [US3] [ENV:build] Run the existing src/test/org/rvsnoop/ suite (no broker) after each library block lands to confirm no behaviour regression the tests can see; record the green run against US3 acceptance [roadmap] 002 — DuckDB Project Persistence (replace db4o) #2 (FR-011, SC-010)
  • T022 [US3] Retarget com.google.guava:guava r08 → 33.x in gradle/libs.versions.toml (verify latest); record target + Apache-2.0 licence in the ledger (research R3; FR-001/FR-016/FR-017)
  • T023 [US3] Migrate the com.google.common.base.Objects equals/hashCode/toStringHelper helper to MoreObjects/java.util.Objects at the affected sites — src/main/rvsnoop/RvConnection.java, RecordType.java, RecordMatcher.java, RecordSelection.java, SubjectElement.java, RecordTypes.java (research R3; CONTRACT-MIG-1; FR-007) — Preconditions.checkArgument/checkNotNull are stable, no change
  • T024 [P] [US3] [ENV:build] Recompile the remaining ~14 com.google.common.* users and fix any other removed/renamed API surfaced by the compiler in src/main/org/rvsnoop/RvMessageTreeNode.java, RvFieldTreeNode.java, XMLTreeNode.java, NLSUtils.java, UserPreferences.java, ProjectService.java, ui/FooterPanel.java, ui/RecordLedgerFormat.java, actions/ExportToFile.java, matchers/DataAccessorFactory.java, matchers/PredicateFactory.java, matchers/DataAccessor.java, matchers/Predicate.java (research R3; CONTRACT-MIG-1; FR-007)
  • T025 [US3] [ENV:build] Confirm exactly one Guava version resolves after the bump (no transitive Guava pulled by another lib), adjusting the T006 force block if needed (FR-008/FR-009; CONTRACT-DEP-2)
  • T026 [US3] Change the Glazed Lists coordinate in gradle/libs.versions.toml: net.java.dev.glazedlists:glazedlists_java15:1.7.0com.glazedlists:glazedlists (verify coordinate + latest version); record target + licence (LGPL-2.1/MPL-1.1 dual, pre-existing — verify the new coordinate keeps a compatible posture, flag the maintainer if changed) in the ledger (research R4; FR-001/FR-016/FR-017; CONTRACT-MIG-1)
  • T027 [US3] [ENV:build] Migrate removed/renamed ca.odell.glazedlists.* API across the ~21 importing files (the EventList<Record>/Matcher<Record>/FilteredLedgerView record-table + filter stack), guided by the compiler; preserve behaviour (research R4; CONTRACT-MIG-1; FR-007)
  • T028 [US3] Apply the T005 BSAF/beansbinding decision in gradle/libs.versions.toml: pin-latest-viable-on-17 (default) or the recorded vendor-patched/replace escalation for org.bsaf:bsaf:1.9 and org.jdesktop:beansbinding:1.2.1; record decision + licence (BSAF BSD-style; beansbinding LGPL/BSD — verify Apache-compatibility) in the ledger (research R5; CONTRACT-MIG-6; FR-001/FR-016/FR-017)
  • T029 [P] [US3] [ENV:build] Migrate any changed org.jdesktop.application (BSAF, ~17 files driving app lifecycle/@Actions/resource injection) and beansbinding (data-bound dialog) call sites surfaced by the compiler at the pinned versions; preserve behaviour (research R5; FR-007)
  • T030 [P] [US3] Retarget jgoodies Forms in gradle/libs.versions.toml: com.jgoodies:forms:1.2.0com.jgoodies:jgoodies-forms:1.9.x (verify coordinate + version); migrate the 2 dialogs src/main/rvsnoop/ui/RvConnectionDialog.java and src/main/rvsnoop/ui/RvDetailsPanel.java if the API changed; record licence (BSD) (research R6; CONTRACT-MIG-1/5; FR-001/FR-007/FR-016)
  • T031 [P] [US3] Retarget commons-cli:commons-cli 1.2 → current 1.x (verify latest) in gradle/libs.versions.toml; migrate the single site src/main/org/rvsnoop/ui/RvSnoopApplication.java, replacing deprecated OptionBuilder with Option.builder(); record licence (Apache-2.0) (research R6; CONTRACT-MIG-1/3; FR-001/FR-007/FR-016)
  • T032 [P] [US3] Retarget xom:xom 1.2.6 → 1.3.x (verify latest) in gradle/libs.versions.toml; migrate any changed nu.xom.* API across the ~9 project/config read-write files; record licence (LGPL-2.1, pre-existing — verify Apache-compatibility) (research R6; CONTRACT-MIG-1/4; FR-001/FR-007/FR-016)
  • T033 [US3] [ENV:launch] Validate quickstart Scenario 4 (record table sort/filter/select/binding; form dialogs; command-line options; XML round-trip — all unchanged) and Scenario 8 (BSAF/beansbinding run on 17 or carry a documented decision) (CONTRACT-MIG-2/3/4/5/6; FR-014, SC-010)

Phase 6: User Story 4 - Test framework is current and reliable (Priority: P3)

  • T034 [P] [US4] [ENV:build] After the framework bump, run the full suite and diff the discovered/executed test list against the T003 pre-upgrade baseline to prove none was silently dropped — incl. InMemoryLedgerTest, FilteredLedgerViewTest, NLSUtilsTest (the abstract RecordLedgerTest stays excluded per 001) under src/test/org/rvsnoop/ (CONTRACT-TEST-1; FR-010, SC-005)
  • T035 [P] [US4] [ENV:ci] Add an intentionally-failing test on a throwaway branch and confirm CI reports it and blocks merge under 001's green-only policy, then remove it (CONTRACT-TEST-3; FR-012, US4 acceptance [roadmap] 003 — Upgrade Dependencies to Current Versions #3)
  • T036 [US4] Retarget junit:junit 4.4 → 4.13.2 (verify latest 4.x) in gradle/libs.versions.toml; record licence (EPL-1.0) in the ledger (research R7; FR-001/FR-010/FR-016) — (only if JUnit 5 is selected instead) add the JUnit 5 + Vintage-engine dependencies, switch the build to useJUnitPlatform(), and keep/rewrite the two junit.framework.TestCase classes so no test is dropped (research R7 [CLARIFY]; SC-005)
  • T037 [US4] [ENV:build] Confirm the two JUnit-3-style classes (junit.framework.TestCase) still compile and run under 4.13.2 (or under the Vintage engine if JUnit 5 was chosen) — src/test/org/rvsnoop/ (CONTRACT-TEST-1; FR-010, SC-005)
  • T038 [US4] [ENV:ci] Validate quickstart Scenario 5: full suite passes on Java 17 without a broker, same test count as before, results reported on the PR as in 001 (CONTRACT-TEST-1/2; FR-010/FR-011/FR-012, SC-005)

Phase 7: Polish & Cross-Cutting Concerns

  • T039 [P] Finalise the upgrade-decision ledger specs/003-dependency-upgrades/upgrade-decisions.md: every in-scope library carries a target + decision + rationale + recorded licence; flip verified to yes once confirmed against a real build; confirm none remains in the original 2007–2011 state without a record (FR-001/FR-017; SC-004, CONTRACT-DEP-1)
  • T040 [P] Licence sweep: confirm every chosen target is Apache-2.0-compatible with no NEW copyleft introduced (Glazed Lists / XOM dual/copyleft licences are pre-existing, not introduced here) and recorded (Constitution I; FR-016; SC-007, CONTRACT-DEP-3)
  • T041 [ENV:build] Run the Gradle dependency report and confirm exactly one version per library with no unresolved conflict (ASM/cglib, Guava, SLF4J pinned via the T006 force/constraints block) (FR-008/FR-009; SC-006, CONTRACT-DEP-2)
  • T042 [ENV:build] Confirm the build completes offline with a warm cache after all bumps (Constitution IV; FR-018; SC-006, CONTRACT-DEP-4)
  • T043 [P] [ENV:ci] Confirm Dependabot (configured by 001 for the gradle ecosystem) now tracks every upgraded library at its new pinned version and continues proposing updates (FR-013; CONTRACT-DEP-5)
  • T044 Re-confirm the db4o guard: its gradle/libs.versions.toml pin is byte-identical to feature 001's, nothing in this feature's change set touches db4o, and the Java-17 launch (Scenario 1) succeeded regardless of db4o (FR-015; SC-008, CONTRACT-DEP-6; quickstart Scenario 9)
  • T045 [ENV:ci] Confirm CI compiles + tests the upgraded project on every push/PR on Java 17 and reports results on the PR with no regression to 001; a red build (compile error, test failure, or unresolved dependency conflict) blocks merge (FR-012; SC-009, CONTRACT-CI-1/2; quickstart Scenario 6)
  • T046 [ENV:launch] Run the full quickstart.md validation (Scenarios 1–9), confirming the two GO/NO-GO gates (Scenario 1 DI-on-17, Scenario 7 single-version + offline) and the BSAF edge (Scenario 8) all pass (all FR-/SC-/CONTRACT- ids)

Metadata

Metadata

Assignees

No one assigned

    Labels

    roadmapSpec-kit roadmap feature (draft plan)

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions