Need help implementing Java modules

Remi Forax forax at univ-mlv.fr
Wed May 10 06:50:15 UTC 2017



On May 10, 2017 2:20:31 AM GMT+02:00, Ralph Goers <rgoers at apache.org> wrote:
>
>> On May 9, 2017, at 3:39 PM, Alex Buckley <alex.buckley at 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?

It depends if when you call the static method you need to bypass the encapsulation or not i.e. if your current code uses setAccessible, yes, the plugin's module has to be opened.

In any case, you need to add a read edge at runtime from log4j to the plugin, otherwise you will not find the plugins class.

> I am assuming that Log4j will be able to access this
>module without having to declare a dependency on it? 

yes, if you add a read edge at runtime.

>
>Thanks,
>Ralph

cheers,
Rémi 

-- 
Sent from my Android device with K-9 Mail. Please excuse my brevity.


More information about the jigsaw-dev mailing list