This is an automated email from the ASF dual-hosted git repository.
jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git
The following commit(s) were added to refs/heads/master by this push:
new f300813885 refactor: remove global init state from ArgsVar and
ManifestFileVar
f300813885 is described below
commit f300813885fcd6ba66221c3865550f60b28996f0
Author: James Bognar <[email protected]>
AuthorDate: Thu May 14 12:30:09 2026 -0400
refactor: remove global init state from ArgsVar and ManifestFileVar
---
.../apache/juneau/commons/svl/vars/ArgsVar.java | 28 ++++------------------
.../juneau/commons/svl/vars/ManifestFileVar.java | 26 ++++----------------
.../apache/juneau/microservice/Microservice.java | 4 +++-
.../juneau/commons/svl/vars/PropertyVars_Test.java | 25 ++++++++-----------
todo/TODO.md | 6 -----
5 files changed, 21 insertions(+), 68 deletions(-)
diff --git
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/svl/vars/ArgsVar.java
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/svl/vars/ArgsVar.java
index 1d8dbf38a2..2bf1e75ae8 100644
---
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/svl/vars/ArgsVar.java
+++
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/svl/vars/ArgsVar.java
@@ -16,7 +16,6 @@
*/
package org.apache.juneau.commons.svl.vars;
-import java.util.concurrent.atomic.*;
import java.util.function.*;
import org.apache.juneau.commons.runtime.*;
@@ -37,7 +36,6 @@ import org.apache.juneau.commons.svl.*;
* <ul class='spaced-list'>
* <li><js>"sun.java.command"</js> system property.
* <li><js>"juneau.args"</js> system property.
- * <li>{@link #init(Args)} has been called.
* <li>The instance was created via {@link #create(Supplier)}.
* </ul>
*
@@ -46,10 +44,8 @@ import org.apache.juneau.commons.svl.*;
* <jc>// Create an args object from the main(String[]) method.</jc>
* Args <jv>args</jv> = <jk>new</jk> Args(<jv>argv</jv>);
*
- * ArgsVar.<jsm>init</jsm>(<jv>args</jv>);
- *
* <jc>// Create a variable resolver that resolves JVM arguments (e.g.
"$A{1}")</jc>
- * VarResolver <jv>varResolver</jv> =
VarResolver.<jsm>create</jsm>().vars(ArgsVar.<jk>class</jk>).build();
+ * VarResolver <jv>varResolver</jv> =
VarResolver.<jsm>create</jsm>().vars(ArgsVar.<jsm>create</jsm>(() ->
<jv>args</jv>)).build();
*
* <jc>// Use it!</jc>
* System.<jsf>out</jsf>.println(<jv>varResolver</jv>.resolve(<js>"Arg #1
is set to $A{1}"</js>));
@@ -68,28 +64,12 @@ public class ArgsVar extends DefaultingVar {
/** The name of this variable. */
public static final String NAME = "A";
- private static final AtomicReference<Supplier<Args>>
STATIC_ARGS_SUPPLIER = new
AtomicReference<>(ArgsPropertySource::createDefaultArgs);
-
- /**
- * Initialize the args for this variable.
- *
- * <p>
- * This sets a process-wide reference that all newly-constructed {@link
ArgsVar} instances will read from. For
- * isolated, per-resolver state without mutating global state, use
{@link #create(Supplier)} instead.
- *
- * @param args The parsed command-line arguments.
- */
- public static void init(Args args) {
- STATIC_ARGS_SUPPLIER.set(() -> args);
- }
-
/**
* Creates an {@link ArgsVar} bound to a per-instance {@link Supplier}
of {@link Args}.
*
* <p>
- * Use this when wiring an {@link ArgsVar} into a single {@code
VarResolver} without mutating the process-wide
- * state established by {@link #init(Args)}. The supplier is invoked
on every resolve, so callers can update the
- * underlying {@link Args} between resolves if needed.
+ * The supplier is invoked on every resolve, so callers can update the
underlying {@link Args} between resolves if
+ * needed.
*
* @param supplier The supplier of {@link Args} for this var instance.
Must not be <jk>null</jk>.
* @return A new {@link ArgsVar} instance backed by the supplier.
@@ -105,7 +85,7 @@ public class ArgsVar extends DefaultingVar {
*/
public ArgsVar() {
super(NAME);
- this.source = new ArgsPropertySource(() ->
STATIC_ARGS_SUPPLIER.get().get());
+ this.source = new
ArgsPropertySource(ArgsPropertySource::createDefaultArgs);
}
private ArgsVar(Supplier<Args> supplier) {
diff --git
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/svl/vars/ManifestFileVar.java
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/svl/vars/ManifestFileVar.java
index bc6a3fdd90..cfce520517 100644
---
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/svl/vars/ManifestFileVar.java
+++
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/svl/vars/ManifestFileVar.java
@@ -31,7 +31,7 @@ import org.apache.juneau.commons.svl.*;
* <p>
* This variable resolver requires that a {@link ManifestFile} object be made
available by either:
* <ul class='spaced-list'>
- * <li>Calling {@link #init(ManifestFile)} (process-wide).
+ * <li>Classpath/default manifest discovery when using the no-arg
constructor.
* <li>Constructing the var via {@link #create(Supplier)} (per-instance).
* </ul>
*
@@ -40,10 +40,8 @@ import org.apache.juneau.commons.svl.*;
* <jc>// Create a ManifestFile object that contains the manifest of the
jar file containing this class.</jc>
* ManifestFile <jv>manifestFile</jv> = <jk>new</jk>
ManifestFile(<jk>this</jk>.getClass());
*
- * ManifestFileVar.<jsm>init</jsm>(<jv>manifestFile</jv>);
- *
* <jc>// Create a variable resolver that resolves manifest file entries
(e.g. "$MF{Main-Class}")</jc>
- * VarResolver <jv>varResolver</jv> =
VarResolver.<jsm>create</jsm>().vars(ManifestFileVar.<jk>class</jk>).build();
+ * VarResolver <jv>varResolver</jv> =
VarResolver.<jsm>create</jsm>().vars(ManifestFileVar.<jsm>create</jsm>(() ->
<jv>manifestFile</jv>)).build();
*
* <jc>// Use it!</jc>
* System.<jsf>out</jsf>.println(<jv>varResolver</jv>.resolve(<js>"The
main class is $MF{Main-Class}"</js>));
@@ -62,27 +60,11 @@ public class ManifestFileVar extends DefaultingVar {
/** The name of this variable. */
public static final String NAME = "MF";
- private static volatile Supplier<ManifestFile> manifestSupplier = () ->
null;
-
- /**
- * Initialize the manifest file for this variable.
- *
- * <p>
- * This sets a process-wide reference that all newly-constructed {@link
ManifestFileVar} instances will read from.
- * For isolated, per-resolver state without mutating global state, use
{@link #create(Supplier)} instead.
- *
- * @param manifestFile The parsed manifest file.
- */
- public static void init(ManifestFile manifestFile) {
- ManifestFileVar.manifestSupplier = () -> manifestFile;
- }
-
/**
* Creates a {@link ManifestFileVar} bound to a per-instance {@link
Supplier} of {@link ManifestFile}.
*
* <p>
- * Use this when wiring a {@link ManifestFileVar} into a single {@code
VarResolver} without mutating the
- * process-wide state established by {@link #init(ManifestFile)}. The
supplier is invoked on every resolve.
+ * The supplier is invoked on every resolve.
*
* @param supplier The supplier of {@link ManifestFile} for this var
instance. Must not be <jk>null</jk>.
* @return A new {@link ManifestFileVar} instance backed by the
supplier.
@@ -98,7 +80,7 @@ public class ManifestFileVar extends DefaultingVar {
*/
public ManifestFileVar() {
super(NAME);
- this.source = new ManifestFilePropertySource(() ->
manifestSupplier.get());
+ this.source = ManifestFilePropertySource.createDefault();
}
private ManifestFileVar(Supplier<ManifestFile> supplier) {
diff --git
a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/Microservice.java
b/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/Microservice.java
index 787af6bbe3..b20f9aa349 100755
---
a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/Microservice.java
+++
b/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/Microservice.java
@@ -612,8 +612,10 @@ public class Microservice implements ConfigEventListener {
}
manifest2 = new ManifestFile(m);
}
- ManifestFileVar.init(manifest2);
this.manifest = manifest2;
+ builder.varResolver
+ .vars(ArgsVar.create(() -> this.args))
+ .vars(ManifestFileVar.create(() -> this.manifest));
//
--------------------------------------------------------------------------------
// Try to resolve the configuration if not specified.
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/commons/svl/vars/PropertyVars_Test.java
b/juneau-utest/src/test/java/org/apache/juneau/commons/svl/vars/PropertyVars_Test.java
index 9bee2df31a..f55fe419c0 100644
---
a/juneau-utest/src/test/java/org/apache/juneau/commons/svl/vars/PropertyVars_Test.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/commons/svl/vars/PropertyVars_Test.java
@@ -33,24 +33,21 @@ class PropertyVars_Test extends TestBase {
//====================================================================================================
@Test
- void a01_argsVar_init_resolvesPositional() {
- ArgsVar.init(new Args("hello world"));
- var vr = VarResolver.create().vars(ArgsVar.class).build();
+ void a01_argsVar_create_resolvesPositional() {
+ var vr = VarResolver.create().vars(ArgsVar.create(() -> new
Args("hello world"))).build();
assertEquals("hello", vr.resolve("$A{0}"));
assertEquals("world", vr.resolve("$A{1}"));
}
@Test
- void a02_argsVar_init_resolvesNamed() {
- ArgsVar.init(new Args("-port 9999"));
- var vr = VarResolver.create().vars(ArgsVar.class).build();
+ void a02_argsVar_create_resolvesNamed() {
+ var vr = VarResolver.create().vars(ArgsVar.create(() -> new
Args("-port 9999"))).build();
assertEquals("9999", vr.resolve("$A{port}"));
}
@Test
- void a03_argsVar_init_missingKey_returnsDefault() {
- ArgsVar.init(new Args("-port 9999"));
- var vr = VarResolver.create().vars(ArgsVar.class).build();
+ void a03_argsVar_create_missingKey_returnsDefault() {
+ var vr = VarResolver.create().vars(ArgsVar.create(() -> new
Args("-port 9999"))).build();
assertEquals("defaultVal", vr.resolve("$A{host,defaultVal}"));
}
@@ -73,22 +70,20 @@ class PropertyVars_Test extends TestBase {
//====================================================================================================
@Test
- void b01_manifestFileVar_init_resolvesKey() {
+ void b01_manifestFileVar_create_resolvesKey() {
var manifest = new Manifest();
manifest.getMainAttributes().putValue("My-Attr",
"from-manifest");
- ManifestFileVar.init(new ManifestFile(manifest));
- var vr =
VarResolver.create().vars(ManifestFileVar.class).build();
+ var vr = VarResolver.create().vars(ManifestFileVar.create(() ->
new ManifestFile(manifest))).build();
assertEquals("from-manifest", vr.resolve("$MF{My-Attr}"));
}
@Test
- void b02_manifestFileVar_init_missingKey_returnsEmptyString() {
+ void b02_manifestFileVar_create_missingKey_returnsEmptyString() {
// ManifestFileVar.resolve() returns "" (not null) for missing
keys,
// so DefaultingVar does not apply the default — empty string
is returned.
var manifest = new Manifest();
manifest.getMainAttributes().putValue("My-Attr", "x");
- ManifestFileVar.init(new ManifestFile(manifest));
- var vr =
VarResolver.create().vars(ManifestFileVar.class).build();
+ var vr = VarResolver.create().vars(ManifestFileVar.create(() ->
new ManifestFile(manifest))).build();
assertEquals("", vr.resolve("$MF{Missing-Attr}"));
assertEquals("",
vr.resolve("$MF{Missing-Attr,ignored-default}"));
}
diff --git a/todo/TODO.md b/todo/TODO.md
index 3456d025f8..735de94721 100644
--- a/todo/TODO.md
+++ b/todo/TODO.md
@@ -21,14 +21,10 @@
- [TODO-12] Schema validation mode for parsers and serializers: wire `@Schema`
validation into the bean property get/set lifecycle gated by a new
`validateSchema` flag on `MarshallingContext`. See
`todo/TODO-12-schema-validation.md`.
-- [TODO-13] Convert Juneau system properties to the `Settings` class in
`juneau-commons`. See
`todo/TODO-13-system-properties-to-settings-conversion.md`.
-
- [TODO-17] Audit 9.2.x changes (juneau-docs release notes 9.2.0 / 9.5.0 + git
history since 9.1.0) for breaking changes and populate the v9.5 Migration Guide
at juneau-docs/pages/topics/23.01.V9.5-migration-guide.md with Old→New rows for
each. Focus on removed APIs, renamed annotations/classes/methods, changed
default behaviors, and any annotation-attribute semantics changes.
- [TODO-18] Investigate possible useful features to add to juneau-rest-server.
-- [TODO-19] Deprecate the static `init(...)` / `AtomicReference` state on
`ArgsVar` and `ManifestFileVar` in favor of the per-resolver `Supplier<Args>` /
`Supplier<ManifestFile>` overloads added in TODO-14. Target a post-9.5 release.
Follow-up to TODO-14.
-
- [TODO-20] Rethink how debugging works in RestServlet. Can we come up with a
simpler system?
- [TODO-21] Bean / inject annotation rename and commons.inject surface
cleanup. See `todo/TODO-21-bean-annotations-inject-package.md`.
@@ -39,7 +35,5 @@
- [TODO-24] JSR-330 alignment (no `jakarta.inject-api` dependency) + selective
Spring-lite features for `commons.inject`. See
`todo/TODO-24-jsr330-and-spring-lite-support.md`.
-- [TODO-27] Design a unified property-source hierarchy for `juneau-commons`
that abstracts over `Args`, `ManifestFile`, environment variables, system
properties, `.env` files, and `Config`. Goal: one `PropertySource` interface
that vars and the bean store can compose, with stacking/precedence rules.
Follow-up to TODO-14 and overlaps with TODO-13.
-
- [TODO-30] Investigate moving `ClassMeta` and related non-marshalling type
metadata from `juneau-marshall` into `juneau-commons` (analysis/feasibility
pass). See `todo/TODO-30-classmeta-to-commons.md`.