After an attempt at soloing the idea, I’ve reverted my changes and am instead documenting the current system along with adding some proposals in the following Confluence doc [0]. I’ve analyzed the initialization ordering of the API (without going into detail of how log4j-core initializes as this differs fairly significantly in 2.x and 3.x at this point). Right now, some of the main differences between 2.x and master is that most of the documented static fields from initialization are currently refactored into Lazy<T> static fields, though that only defers initialization until slightly later.
I’d like to work on a proper SPI here so that I can get back to considering updates to log4j-core and dependency injection. In general, my idea is to add a getInstance(Class<T>) method to the API provider class which would be used to get the LoggerContextFactory along with initial instances for ThreadContextMap and ThreadContextFactory. This could become a natural place to also return a PropertyEnvironment instance (the interface that PropertiesUtil now implements) to further avoid use of static state. Let me know what you think of the idea. Do we need a separate log4j-spi module? Other ideas? [0]: https://cwiki.apache.org/confluence/display/LOGGING/API+Initialization — Matt Sicker