Fwd: Module naming for logging implementations

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Fwd: Module naming for logging implementations

Stephen Colebourne
(previously posted on core-libs-dev, moved by request)

I've spent some time discussing module names for logging
implementations recently:
https://github.com/jodastephen/jpms-module-names/wiki/Logging-APIs
https://issues.apache.org/jira/browse/LOG4J2-2056
https://jira.qos.ch/browse/SLF4J-407?jql=text%20~%20%22jpms%22

Most logging projects are split in two - an API and an Implementation
- where the recommended solution going forwards is to use
ServiceLoader to find the implementations. A few old projects don't
have this split, and have API and Implementation together (eg
Commons-Logging).

Everyone agrees that the module name for the API must always be the
same. ie. if the SLF4J team provides a module that simulates the
Commons-Logging then it must have the same module name as
Commons-Logging.

However, there are two choices for the implementation jars.

Option 1:
All modules that implement a particular logging API must have the same
module name
eg. every module that implements "org.slf4j" (the API) must be named
"org.slf4j.impl"

Option 2:
The module name of the implementation can be whatever name makes sense.


For most service providers, option 2 is obvious, however for logging
it is generally the case that only one implementation should be
present. If all the jar files that implement a specific logging API
had the same module name (option 1) then the module system could
ensure that only one was loaded. This is a particular concern as it is
not uncommon for a jar file in Maven Central to depend on a specific
implementation of logging when it should only be depending on the API.


I'm leaning towards option 2, as it is simpler and does not require
all implementations to have the same module name (which would be
difficult to require). Any other considerations I'm missing?

Stephen
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: Module naming for logging implementations

Alex Buckley
On 10/26/2017 1:03 PM, Stephen Colebourne wrote:
> (previously posted on core-libs-dev, moved by request)

(Thanks!)

> Option 1:
> All modules that implement a particular logging API must have the same
> module name
> eg. every module that implements "org.slf4j" (the API) must be named
> "org.slf4j.impl"
>
> Option 2:
> The module name of the implementation can be whatever name makes sense.
>
>
> For most service providers, option 2 is obvious, however for logging
> it is generally the case that only one implementation should be
> present. If all the jar files that implement a specific logging API
> had the same module name (option 1) then the module system could
> ensure that only one was loaded. This is a particular concern as it is
> not uncommon for a jar file in Maven Central to depend on a specific
> implementation of logging when it should only be depending on the API.
>
>
> I'm leaning towards option 2, as it is simpler and does not require
> all implementations to have the same module name (which would be
> difficult to require). Any other considerations I'm missing?

Option 1 opens the door to multiple modules with the same name being
placed in different directories of the modulepath. Not a good place to
be, even if no-one is targeting them via 'requires'.

(I think ServiceLoader does not care about duplicate module names when
scanning modules on the modulepath, and will inspect their 'provides'
directives regardless. However, I confess that I cannot figure out from
the ServiceLoader spec which modules are observable during binding.)

Stepping back, there are two big anti-patterns in the world of
ServiceLoader. First, it is an anti-pattern for a provider module to
'exports' its provider implementation. Second, it is an anti-pattern for
a consumer module to 'requires' a particular provider module. Option 2
fights the second anti-pattern by making provider modules not "stand
out" more than other modules. This in turn fights the first
anti-pattern, because a provider module that is not expecting to be
mentioned in 'requires' will not hurry to 'exports' anything. (Yes, this
is all a bit soft, but programming with services is primarily about
mindset.)

Alex
Reply | Threaded
Open this post in threaded view
|

Re: Module naming for logging implementations

David M. Lloyd
In reply to this post by Stephen Colebourne
On Thu, Oct 26, 2017 at 3:03 PM, Stephen Colebourne
<[hidden email]> wrote:
> For most service providers, option 2 is obvious, however for logging
> it is generally the case that only one implementation should be
> present. If all the jar files that implement a specific logging API
> had the same module name (option 1) then the module system could
> ensure that only one was loaded. This is a particular concern as it is
> not uncommon for a jar file in Maven Central to depend on a specific
> implementation of logging when it should only be depending on the API.

This is actually a general special case (if you follow my meaning):
that of an API which uses services to locate an implementation, yet
typically only one implementation should be existent and used.  For
example, I/O or other platform-dependent systems also spring to mind:
they have a common API, but you generally only want one implementation
(except maybe in some special cases - just like for logging).

I think that in any case, be it a singleton-ish provider case like one
of the above or a multiple-provider case, it is always appropriate to
choose a unique module name for implementations. It's not appropriate
for an API to prescribe an implementation module name.

Perhaps we can enhance Jigsaw in the future with some kind of feature
that enforces singleton implementations, if it becomes any sort of
practical problem.

--
- DML
Reply | Threaded
Open this post in threaded view
|

Re: Module naming for logging implementations

Gregg Wonderly
In reply to this post by Stephen Colebourne
I’d like to reverse this dependency to be that in the end, I want every module in the app I construct to funnel through and use a single Logging implementation so that I can linearize the logging streams into a single stream of details that help me to understand the health and progress of my application.  I want to make sure that I can provide this logging merge apparatus without having to jump through hoops.  Yes, I need to have something that provides all APIs, but those all will be from a single module, not one module per API, because I don’t want to have to create such an layered web of modules.

Removing the logging dependency resolution from module references to ServiceLayer resolution helps me to do this by deferring the task to runtime.  I like that notion because it helps me be able to construct all the objects and implementation details, and then the logging users can find my merged logging implementation, instead of me having to reference the dependency graph and figure out how to make 5 modules accept dependency injections that allow me to make them work, when I may not know all of the details of their “activation”.

Gregg

> On Oct 26, 2017, at 5:05 PM, David Lloyd <[hidden email]> wrote:
>
> On Thu, Oct 26, 2017 at 3:03 PM, Stephen Colebourne
> <[hidden email]> wrote:
>> For most service providers, option 2 is obvious, however for logging
>> it is generally the case that only one implementation should be
>> present. If all the jar files that implement a specific logging API
>> had the same module name (option 1) then the module system could
>> ensure that only one was loaded. This is a particular concern as it is
>> not uncommon for a jar file in Maven Central to depend on a specific
>> implementation of logging when it should only be depending on the API.
>
> This is actually a general special case (if you follow my meaning):
> that of an API which uses services to locate an implementation, yet
> typically only one implementation should be existent and used.  For
> example, I/O or other platform-dependent systems also spring to mind:
> they have a common API, but you generally only want one implementation
> (except maybe in some special cases - just like for logging).
>
> I think that in any case, be it a singleton-ish provider case like one
> of the above or a multiple-provider case, it is always appropriate to
> choose a unique module name for implementations. It's not appropriate
> for an API to prescribe an implementation module name.
>
> Perhaps we can enhance Jigsaw in the future with some kind of feature
> that enforces singleton implementations, if it becomes any sort of
> practical problem.
>
> --
> - DML

Reply | Threaded
Open this post in threaded view
|

Re: Module naming for logging implementations

Stephen Colebourne
In reply to this post by David M. Lloyd
Thanks Alex and David, those are good arguments. So option 2 it is.
Stephen

On 26 October 2017 at 23:05, David Lloyd <[hidden email]> wrote:

> On Thu, Oct 26, 2017 at 3:03 PM, Stephen Colebourne
> <[hidden email]> wrote:
>> For most service providers, option 2 is obvious, however for logging
>> it is generally the case that only one implementation should be
>> present. If all the jar files that implement a specific logging API
>> had the same module name (option 1) then the module system could
>> ensure that only one was loaded. This is a particular concern as it is
>> not uncommon for a jar file in Maven Central to depend on a specific
>> implementation of logging when it should only be depending on the API.
>
> This is actually a general special case (if you follow my meaning):
> that of an API which uses services to locate an implementation, yet
> typically only one implementation should be existent and used.  For
> example, I/O or other platform-dependent systems also spring to mind:
> they have a common API, but you generally only want one implementation
> (except maybe in some special cases - just like for logging).
>
> I think that in any case, be it a singleton-ish provider case like one
> of the above or a multiple-provider case, it is always appropriate to
> choose a unique module name for implementations. It's not appropriate
> for an API to prescribe an implementation module name.
>
> Perhaps we can enhance Jigsaw in the future with some kind of feature
> that enforces singleton implementations, if it becomes any sort of
> practical problem.
>
> --
> - DML
Reply | Threaded
Open this post in threaded view
|

Re: Module naming for logging implementations

Cédric Champeau
There's a good argument for 1, though. log4j typically doesn't separate api
and implementation. So a module would "require 'log4j'". It means that if
another module like slf4j doesn't "pretend to be" log4j, it's now going to
fail. Said differently, Jigsaw kills module replacements and fatjars.

2017-10-27 0:26 GMT+02:00 Stephen Colebourne <[hidden email]>:

> Thanks Alex and David, those are good arguments. So option 2 it is.
> Stephen
>
> On 26 October 2017 at 23:05, David Lloyd <[hidden email]> wrote:
> > On Thu, Oct 26, 2017 at 3:03 PM, Stephen Colebourne
> > <[hidden email]> wrote:
> >> For most service providers, option 2 is obvious, however for logging
> >> it is generally the case that only one implementation should be
> >> present. If all the jar files that implement a specific logging API
> >> had the same module name (option 1) then the module system could
> >> ensure that only one was loaded. This is a particular concern as it is
> >> not uncommon for a jar file in Maven Central to depend on a specific
> >> implementation of logging when it should only be depending on the API.
> >
> > This is actually a general special case (if you follow my meaning):
> > that of an API which uses services to locate an implementation, yet
> > typically only one implementation should be existent and used.  For
> > example, I/O or other platform-dependent systems also spring to mind:
> > they have a common API, but you generally only want one implementation
> > (except maybe in some special cases - just like for logging).
> >
> > I think that in any case, be it a singleton-ish provider case like one
> > of the above or a multiple-provider case, it is always appropriate to
> > choose a unique module name for implementations. It's not appropriate
> > for an API to prescribe an implementation module name.
> >
> > Perhaps we can enhance Jigsaw in the future with some kind of feature
> > that enforces singleton implementations, if it becomes any sort of
> > practical problem.
> >
> > --
> > - DML
>
Reply | Threaded
Open this post in threaded view
|

Re: Module naming for logging implementations

Stephen Colebourne
On 26 October 2017 at 23:35, Cédric Champeau <[hidden email]> wrote:
> There's a good argument for 1, though. log4j typically doesn't separate api
> and implementation. So a module would "require 'log4j'". It means that if
> another module like slf4j doesn't "pretend to be" log4j, it's now going to
> fail. Said differently, Jigsaw kills module replacements and fatjars.

Module replacements like log4j v1 work exactly as today. There is one
extra requirement that as well as having the same package name, the
replacement must have the same module name.

Fatjars are certainly of no use as a dependency with the current
jigsaw design, but logging doesn't seem to use fatjars.

Stephen