In this particular scenario, a file URI has been provided to the LoggerContext 
constructor. Given the fact that a Logger instance itself is not constructed 
until _after_ the LoggerContext has been constructed, no logging can possibly 
occur until at least after said construction. In our current implementation, we 
always load a DefaultConfiguration in LoggerContext before reconfiguring to use 
the real config.

This applies to any possible ContextSelector, by the way, since those control 
the creation of LoggerContext instances in the first place (unless you’re using 
something lower level to start things up like one of the LoggerContext 
constructors I’m referring to, but that’s always handled by the underlying 
ContextSelector in Core). The Java memory model guarantees that constructing a 
class is an atomic operation; the result of the constructor is safely published 
and available for any and all threads to consume. This is the main reason why 
using the `final` keyword is useful in Java: final fields in classes are the 
safely published state (assuming the underlying reference is an immutable or 
thread-safe structure of course), and volatile fields require memory fencing 
before doing any reads or writes to them in order for threads to all see the 
same state. In theory, we may be able to load a configuration during the 
constructor which would help avoid all those weird hacks in place by Spring 
Boot et al. for disabling logging until they can bootstrap themselves first.
—
Matt Sicker

> On Dec 19, 2022, at 08:11, Ralph Goers <ralph.go...@dslextreme.com> wrote:
> 
> I am not really sure what the question here is. When you pass in a 
> configuration location you are going to end up with a LoggerContext that 
> references a Configuration derived from the information at that location. 
> Yes, it may create a DefaultConfiguration along the way but that is primarily 
> because logging may need to occur while Log4j is configuring. 
> 
> As for the external context, that was initially created to support binding 
> with things like Spring. However, the way Spring Boot ended up using it 
> caused some issues for adding extended Spring support so the LoggerContext 
> now contains a Map so that multiple “external” values can be captured. The 
> ExternalContext is just stored in a specific key. Given how the injector 
> worked the last time I looked at it I don’t really see how Spring could use 
> it.
> 
> Ralph
> 
> 
> 
>> On Dec 18, 2022, at 12:29 PM, Matt Sicker <m...@musigma.org> wrote:
>> 
>> So I’m working on the properties enhancement issue, and one thing I’ve come 
>> across to clean up are the situations where the LoggerContext may be null in 
>> the constructor to AbstractConfiguration. Previously, this only seemed to be 
>> the case for NullConfiguration, but it may also apply to 
>> DefaultConfiguration during startup. However, suppose I construct a 
>> LoggerContext with a configuration location corresponding to a file (so the 
>> only supported file path type via that constructor). This location does not 
>> get used until the LoggerContext starts; before this, it constructs a 
>> DefaultConfiguration.
>> 
>> During this bootstrapping, if the configuration location is available (such 
>> as for a unit test), should LoggerContext set up the configuration provided? 
>> Or is there some sort of cyclic dependency here preventing us from loading 
>> ConfigurationFactory right away? So far, the only cyclic dependencies I’ve 
>> found are related to plugins created in the DefaultConfiguration (or the 
>> NullConfiguration in some cases), but those are already commented as such 
>> (like in PatternLayout).
>> 
>> I’ll note for reference that LoggerContext has two families of constructors 
>> that fan out into the following parameters:
>> 
>> String name, Object externalContext, String/URI configLocation, Injector 
>> injector, PropertyResolver propertyResolver -> LoggerContext
>> 
>> The external context concept here seems to mainly be used for passing along 
>> a ClassLoader instance or something derived from it (I think a Bundle does 
>> or something from OSGi at least). These constructors do call Injector::init, 
>> so the point of providing an Injector instance here would be if you 
>> preconfigured some beans (like in a unit test) before wanting to load the 
>> default bundles of beans/bindings.
>> —
>> Matt Sicker
>> 
> 

Reply via email to