Need help implementing Java modules

Gregg Wonderly greggwon at cox.net
Wed May 10 20:00:11 UTC 2017


> On May 10, 2017, at 1:58 PM, Alex Buckley <alex.buckley at oracle.com> wrote:
> 
> On 5/9/2017 5:20 PM, Ralph Goers wrote:
>> 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?
> 
> Basically you've got it.
> 
> - The Log4j module does not need to 'requires' any user module, nor invoke addReads to "read" any user module.
> 
> - Log4j code can continue to invoke Class::forName to obtain a Class object for a class in a user module. This is based purely on class loader visibility, no changes from the module system.
> 
> - Log4j code can continue to invoke Class::getMethod et al to obtain a Method object for a static builder/factory method. There are no access control rules when simply "inspecting" the Class object via getMethod, getMethods, getFields, etc.
> 
> - Log4j code can attempt to invoke Method::invoke on its preferred Method object, but for the attempt to succeed, the user module must open or export the class's package. If you mandate that a plugin class must be public with a public builder/factory method, then exporting the package will be enough; otherwise the package needs to be open.
> 
> - I recommend that you recommend that users should open the package to specifically Log4j, rather than opening the package to everyone (or opening the entire module). You said that your JARs will probably be automatic modules for some time, so you can use the Automatic-Module-name manifest entry to introduce a stable name that user modules can open to.

Alex, what will happen to software that is not log4j that wants to use these Appenders?  For something as generic as this, isn’t it really better to just open to everyone?   It just seems more and more like the JDK teams focus on locking people out of the JDK is driving everything in the direction of not sharing code for reuse in most places.  There are very view directed graphs of dependencies in open source code that really need to be anal about what is open.  Software implementing an open/public interface should always be open to all uses of that implementation it seems to me.

Gregg




More information about the jigsaw-dev mailing list