Skip to content

Fix BEAUti startup, duplicate version listing, and example packaging#98

Merged
walterxie merged 1 commit into
masterfrom
fix/beauti-classloader-and-example-packaging
Jun 18, 2026
Merged

Fix BEAUti startup, duplicate version listing, and example packaging#98
walterxie merged 1 commit into
masterfrom
fix/beauti-classloader-and-example-packaging

Conversation

@alexeid

@alexeid alexeid commented Jun 17, 2026

Copy link
Copy Markdown
Member

From Remco's environment testing of the v2.8.0 beta bundle. Three fixes:

1. BEAUti and applauncher crash with ClassNotFoundException (the critical one)

BEAUti would not start and applauncher LogAnalyser -help crashed, both with ClassNotFoundException for beast.fx classes (BeautiConfig, the input editors).

Root cause: a package's service providers are listed in its version.xml. When a version.xml scan registered a provider (via resolveLoaderFor) before the owning beast.fx plugin ModuleLayer was registered, the provider was mapped to the fallback system loader, which can't load it. registerPluginLayer uses putIfAbsent, so it could never replace that stale mapping → forName threw.

Fix (BEASTClassLoader):

  • forName now falls through to the plugin layers on ClassNotFoundException from the mapped loader, and caches the loader that actually resolves the class (self-healing).
  • resolveLoaderFor now also consults registered plugin layers, not just the boot layer.
  • Added a regression test reproducing the stale-mapping scenario.

2. beast -version listed BEAST.base twice

Once from the user package dir, once via the bundle-root version.xml the install dir contributes. printVersion (both copies) now lists each package once, notes where it was found, and reports later duplicates as skipped only in verbose mode.

3. BEAST.base examples were not updatable by a point release

They shipped only in the bundle root, replaced only by a full reinstall. The BEAST.base package zip now includes examples/, so the package manager extracts/updates them in ~/.beast/2.8/BEAST.base/examples on install/upgrade. The three release scripts now extract the bundle-root examples/ from that same package zip, giving the example set a single source of truth (beast-base/src/assembly/package.xml) so the copies can't drift.

Testing done

  • beast-pkgmgmt suite passes (incl. the new regression test).
  • Full reactor mvn package builds clean (all modules + assemblies).
  • Verified the BEAST.base package zip now contains examples/ (41 top-level + spec/ + nexus/) and the release-script extraction produces the expected layout.

⚠️ Caveat — not verified end-to-end

The BEAUti/applauncher fix is covered by a unit regression test but has not been exercised in a real assembled bundle: the bug only manifests when beast.base/beast.fx load as plugin layers from ~/.beast/2.8/ (a dev/IDE run keeps them on the boot module path and won't reproduce it). Walter: please assemble a bundle and confirm beauti, applauncher LogAnalyser -help, and beast -version all behave, then hand on to Remco.

Out of scope (deferred)

  • Shipping source in package dirs (Remco also noted this) — left for now.
  • Native-access warnings on Java 25 (cosmetic).
  • The spurious Skipping modules ... BEAST.app: [beast.fx] message on every run (first-pass skip resolved on retry).

Addresses issues from Remco's environment testing.

BEAUti and `applauncher LogAnalyser` failed with
ClassNotFoundException for beast.fx classes (BeautiConfig and the input
editors). Root cause: a package's service providers are listed in its
version.xml; when a version.xml scan registered a provider (via
resolveLoaderFor) before the owning beast.fx plugin ModuleLayer existed,
the provider was mapped to the fallback system loader, which cannot load
it. registerPluginLayer uses putIfAbsent and so could not replace the
stale mapping, so BEASTClassLoader.forName threw.

  - forName now falls through to the plugin layers on ClassNotFoundException
    from the mapped loader, and caches the loader that actually resolves the
    class (self-healing, so the slow path runs at most once per class).
  - resolveLoaderFor now also consults registered plugin layers, not just
    the boot layer.
  - Added a regression test reproducing the stale-mapping scenario.

`beast -version` listed BEAST.base twice (once from the user package
dir, once via the bundle-root version.xml that the install dir
contributes). printVersion (both the beast-base and beast-fx copies) now
lists each package once, noting where it was found, and reports later
duplicates as skipped only in verbose mode.

BEAST.base examples could not be updated by a point release: they shipped
only in the bundle root, which is replaced only by a full reinstall. The
BEAST.base package zip now includes examples/ (curated to match the
bundle), so the package manager extracts and updates them in
~/.beast/2.8/BEAST.base/examples on install/upgrade. The three release
scripts (Linux/Windows/Mac) now extract the bundle-root examples from
that same package zip, giving the example set a single source of truth
(beast-base/src/assembly/package.xml) so the copies cannot drift.
@alexeid alexeid requested a review from walterxie June 18, 2026 00:01
@walterxie

Copy link
Copy Markdown
Member

tests are passed using Mac release:

bin/beast -version

bin/beauti

bin/packagemanager -add SSM

@walterxie walterxie closed this Jun 18, 2026
@walterxie walterxie merged commit 6373c62 into master Jun 18, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants