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>(() -&gt; 
<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>(() -&gt; 
<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`.
 

Reply via email to