> On May 9, 2017, at 3:39 PM, Alex Buckley <alex.buck...@oracle.com> wrote: > > On 5/9/2017 3:04 PM, Ralph Goers wrote: >> Pardon me for being dense, but my reading said that Java modules >> disallowed runtime cycles as well as compile time. Once LoggerFinder >> binds with the module that provides that service does that not create >> a runtime dependency? I don’t recall seeing anything describing what >> the behavior of that is. > > The module system disallows cycles in the 'requires' directives of module > declarations. The module system allows cycles in the "reads" relation of > run-time modules. > > When java.base 'uses LoggerFinder;' and invokes ServiceLoader to find > providers, there is indeed a "reads" cycle created between the provider > module and java.base. ServiceLoader is not special in creating this cycle -- > you can create them yourself with the two addReads methods in the API, and > all automatic modules have cyclic readability. But there is no 'requires' > cycle. > > Alex >
Thanks Alex, that would indeed be enough to break the cycle as log4j-api can easily use serviceLoader to bind with log4j-core as that is a very minor change. However your previous response leads me to another question. Log4j already has a robust plugin approach for users to implement their own Appenders, Filters, Layouts, and other Log4j components. We are not going to modify that as it would severely impact our users who have already implemented custom components and what we have works very well. Although the FlumeAppender I mentioned previously is provided by Log4j it, and all other Log4j components, are located via an annotation processor provided by Log4j. The processor runs at compile time and generates a file named META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat. All of these files are then located at runtime using ClassLoader.getResources(). As we parse the configuration provided by the user we instantiate the plugins using the class names provided in those files and the static builder or static factory method provided in the plugin class. From what I am reading in the javadoc we should not have any trouble with this because META-INF is not a valid package name so the resource file will not be hidden. Log4j uses reflection to call the static builder or static method to create the plugin. With all this in mind, if users create modules will they be required to declare the packages where they have created plugins as “open” to log4j for this to work? I am assuming that Log4j will be able to access this module without having to declare a dependency on it? Thanks, Ralph