It's mainly to add OSGi support. Since log4j-core (or any of the providers) might not be available at the same time as log4j-api, there needs to be a way to add a LoggerContextFactory afterward to take over. This is due to how OSGi works where you can dynamically add or remove bundles at runtime. Basically, you can't depend on what's available at initialisation to be everything that's there. Plus, you can remove bundles, so you can't rely on classes being there forever (although OSGi won't take them away from you, so it's not that big a deal in that case).
Another example use case would be something like Tomcat or Karaf using Log4j2 internally, but allowing for installed applications (webapps or bundles in these cases) to add more plugins, a different LoggerContextFactory to override, etc. On 14 April 2014 17:40, Remko Popma <[email protected]> wrote: > To be honest, it all sounds pretty complex to me. What is the use case? > You mention you want to dynamically add/remove logger context factories at > runtime but I'm not clear on why this is desired/required. > > If there are class loader issues we should focus on that. If there is an > issue that prevents OSGi from working we should work on that, but I here I > don't see what problem you are trying to solve. Is this for OSGi? > > Instead if diving into the solution, could you provide a clear description > of the problem? > > Remko > > Sent from my iPhone > > On 2014/04/15, at 8:09, Matt Sicker <[email protected]> wrote: > > Alright, here's what I'm thinking so far: > > Add a class named something like LoggerContextFactoryRegistry (yeah I hate > that name already). Make it a singleton class. It should keep a SortedMap > of int -> LoggerContextFactory (similar to how they're scanned in > LogManager). This class should also keep a volatile LoggerContextFactory > containing the current factory so it doesn't have to be recalculated every > time. It can be updated instead when a new factory is registered. > > Method-wise, it should have a getFactory() and a register(int, > LoggerContextFactory) (or call it registerFactory?) method. A lot of the > static initialisation of LogManager can be moved to the constructor in this > class. > > Being able to register the class instance itself (or the class?) works > better than just scanning files due to class loader differences in other > environments. We can't rely on the TCCL or anything like that for every > factory. > > Any feedback? I may end up submitting this as a patch first to get more > feedback, but this part of the implementation may be rather simple overall. > > > On 14 April 2014 11:50, Matt Sicker <[email protected]> wrote: > >> Will do. The main thing I'd like to change is the LogManager >> initialisation. I'd prefer that to keep a registry of >> LoggerContextFactories so that a different factory can be registered later >> on (for instance, in OSGi, you could install log4j-api, then log4j-core, >> and core would register itself and take over as the default factory). >> >> Anything more complex than that (like being able to use multiple >> factories concurrently like you can with contexts), while not necessarily >> requiring API changes, will require some thought as to how and if it's >> feasible. Of course, it would be more of an API addition for that (e.g., >> selecting the non-default provider chooser or something like that). >> Basically, that part shouldn't be hard to make backwards compatible. >> >> >> On 14 April 2014 10:25, Ralph Goers <[email protected]> wrote: >> >>> Hopefully the changes won’t be too significant. Can you please post >>> what you intend to do before commit? >>> >>> Ralph >>> >>> On Apr 14, 2014, at 7:55 AM, Matt Sicker <[email protected]> wrote: >>> >>> I was thinking about how to best support strange class loader >>> environments (like OSGi or Servlets), and in order to support a >>> LoggerContextFactory, we should have a registry of sorts for it. This way, >>> a new LCF can dynamically add or remove itself at runtime. Ideally, we'd >>> fall back to the SimpleLogger implementation when none are registered. >>> There may be an added issue with Loggers being tied to their factories and >>> such. >>> >>> Anyway, the main thing to address is the ability to change (or add) >>> providers at runtime. Whether or not we can support a more dynamic system >>> is more of a technical issue. Scanning for a default provider at >>> initialization still makes sense to pre-load the registry, but imagine the >>> scenario where a server like Tomcat uses Log4j but allows individual web >>> apps to provide custom providers. >>> >>> I'd like to at least implement the necessary API changes before 2.0 so >>> that this may be possible down the line. Even if we don't use OSGi, it >>> should still be possible to use log4j in an OSGi framework (core or as a >>> regular bundle). This will certainly help adoption by the container >>> projects. >>> >>> >>> >>> -- >>> Matt Sicker <[email protected]> >>> >>> >>> >> >> >> -- >> Matt Sicker <[email protected]> >> > > > > -- > Matt Sicker <[email protected]> > > -- Matt Sicker <[email protected]>
