Need help implementing Java modules

Alex Buckley alex.buckley at oracle.com
Wed May 10 18:58:57 UTC 2017


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


More information about the jigsaw-dev mailing list