"pattern we read in a book" heh.
No, a core goal of jetty is to run on as wide an array of hardware as possible.
That means we reuse objects where we can, reduce GC churn, etc.. especially for those resource constrained environments.
We also have to make Jetty's Logging co-exist with the various logging frameworks that are out there now.
All of them initialize at (essentially) JVM start.
Changing them after the fact is not possible.
There are 2 parts of the Logging equation.
1) Emitting Logs from code
2) Runtime Configuration for selecting/filtering/routing Logs to an adapter/appender
The goal of Jetty Logging is to focus on #1, to emit named logging events, with severity, and let the Logging impl decide what to do with them.
The configuration of Logging in #2 is done by the logging implementation you choose. Once a Logger impl is selected it is used.
Your technique of swapping out the Logger selection at runtime is a bug, not a feature. That should never have been allowed.
The change that you keep pointing to (7.0 to 7.6) isn't about static loggers, its about named logging with proper severity.
We went from:
import org.eclipse.jetty.util.Log;
Log.info("Something happened");
to:
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
private static final Logger LOG = Log.getLogger(HelloJettyServlet.class);
LOG.info("Something happened");
Note: the old Log.<severity>(String) methods were marked as deprecated
in jetty-7 and removed
in jetty-9.
This allowed the step #2 folks better control of logging via filtering and routing due to the named loggers.
Since logs then were not instance related then, and logs now are not instance related, there's no reason to have multiple copies of those Loggers in memory.
In fact, having multiple copies of Loggers is viewed as a negative in our minds.
This can be seen our choices in various parts of Jetty, not just the Loggers.
Some examples (off the top of my head, there's lots more)
jetty-http/src/main/java/org/eclipse/jetty/http/DateGenerator.java
private static final ThreadLocal<DateGenerator> __dateGenerator =new ThreadLocal<DateGenerator>()
jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java
private static final Trie<Float> __qualities = new ArrayTernaryTrie<>();
jetty-http/src/main/java/org/eclipse/jetty/http/HttpGenerator.java
private static final PreparedResponse[] __preprepared = new PreparedResponse[HttpStatus.MAX_CODE+1];
jetty-jndi/src/main/java/org/eclipse/jetty/jndi/ContextFactory.java
private static final WeakHashMap __contextMap = new WeakHashMap();
jetty-spdy/spdy-core/src/main/java/org/eclipse/jetty/spdy/api/StreamStatus.java
private static final Map<Integer, StreamStatus> v2Codes = new HashMap<>();
private static final Map<Integer, StreamStatus> v3Codes = new HashMap<>();
jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java
private static final HashMap<String, Class<?>> name2Class=new HashMap<>();
private static final HashMap<Class<?>, String> class2Name=new HashMap<>();
private static final HashMap<Class<?>, Method> class2Value=new HashMap<>();
jetty-websocket/websocket-client/src/main/java/org/eclipse/jetty/websocket/client/ClientUpgradeRequest.java
private static final Set<String> FORBIDDEN_HEADERS;
These fields are static because duplicating them per instance makes no sense.
Could they work as non-static fields? Yes, in all cases. But we wont change that.
Point is, this change is not a "following the herd" or "what we see elsewhere" but rather a conscious decision to minimize pointless GC churn while simultaneously choosing a decision that makes sense for the second part of the Logging equation (configuration).
Years of debate went into this change on the jetty dev side, literally (no foolin!)
Even when the decision was made, more than half the existing devs were nervous / cautious about it.
Today, looking back, the change proved more than needed for the users, but immensely useful for troubleshooting and debugging of servers for us core devs as well.