Load BEAUti templates from the class path, not only module layers - #123
Merged
Conversation
BeautiDoc discovered fxtemplates only inside resolved module layers:
processTemplate -> loadResourceFromModules scans ModuleLayer.boot() plus
plugin layers, and getTemplateSources enumerates them via
BEASTClassLoader.listResources, which does the same. That is correct for
the installed launcher and for 'mvn exec -m beast.fx/...Beauti', where the
beast modules are on the module path and resolved.
But when BEAUti's dependencies are on the class path instead -- embedded
in another tool, or under a test runner where everything loads in the
unnamed module -- no beast.fx module is resolved, so the scans find
nothing and template loading fails with 'Cannot find template:
fxtemplates/Standard.xml', even though the template is right there in the
beast-fx jar.
Add a class-path fallback in both places:
- loadResourceFromModules: after the module scan, try the context
class loader's getResourceAsStream on the namespaced name
(beast.fx/fxtemplates/Standard.xml) and then the bare name.
- getTemplateSources: after the module scan, enumerate fxtemplates/*.xml
by scanning java.class.path entries (jars and directories) and read
each from its resource URL.
Both are additive and last-precedence: in a module-path launch the module
scan still finds everything first and these fallbacks contribute only
duplicates, which are dropped by name. The content is still read from the
jar, never copied out.
beast-fx BeautiSimpleTest still passes unchanged.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Problem
BeautiDocdiscoversfxtemplates/*.xmlonly inside resolved module layers:processTemplate→loadResourceFromModulesscansModuleLayer.boot()+ plugin layers for the main template (Standard.xml).getTemplateSourcesenumerates the merge templates viaBEASTClassLoader.listResources, which scans the same layers.That's correct for the installed launcher and for
mvn exec:exec -m beast.fx/…Beauti, where the beast modules are on the module path and resolved. But when BEAUti's dependencies are on the class path — embedded in another tool, or under a test runner where everything loads in the unnamed module — nobeast.fxmodule is resolved, both scans find nothing, and template loading fails with:…even though the template is right there in the
beast-fxjar atbeast.fx/fxtemplates/Standard.xml.This came up trying to write a headless BEAUti test for a downstream package (bModelTest), where beast-fx is an ordinary jar dependency on the class path.
Change
A class-path fallback in both discovery paths, in
BeautiDoc:loadResourceFromModules— after the module scan, try the context class loader'sgetResourceAsStreamon the namespaced name (beast.fx/fxtemplates/Standard.xml), then the bare name. Works on any class loader.getTemplateSources— after the module scan, enumeratefxtemplates/*.xmlby scanningjava.class.pathentries (jars viaZipFile, directories by listing), reading each from its resource URL via a newUrlTemplateSource.Both are additive and last-precedence: in a module-path launch the module scan finds everything first, and these fallbacks contribute only duplicates, which
getTemplateSourcesalready drops by file name. The content is always read from the jar (or classes dir) via the resource URL — never copied out to disk.Scope is contained to BEAUti template discovery (
getTemplateSourceshas a single caller). No change toBEASTClassLoader.Note: a manifest-only
Class-Pathjar (used by some launchers for very long class paths) is not followed by thejava.class.pathscan; in that layout the module-layer scan is expected to have covered it.Verification
beast-fxBeautiSimpleTestpasses unchanged.Cannot find template: fxtemplates/Standard.xml; after it,Standard.xmlloads from the beast-fx jar andbModelTest.xmlis discovered and merged from the package classes — confirmed in the logs (Loading template from module resource: fxtemplates/Standard.xml,Processing class-path resource …/bmodeltest/fxtemplates/bModelTest.xml).