If I had known this was going to turn into a debate I wouldn’t have responded 
to the 
question. But it seems either my response wasn’t clear, you did not understand 
what I wrote, or you have some preconceived notion as to why anything beyond 
ServiceLoader is needed. I would suggest that before responding to this email 
that 
you go look at how log4j-plugins is implemented in the master branch.

> On Apr 4, 2022, at 8:13 PM, Peter Verhas <pe...@verhas.com> wrote:
> 
> Thank Ralph for the answer related ServiceLoader. I understand your
> concerns. A new commons plugin module is in place if we identify the needs
> unmet with modern Java. However, the shortcomings you listed are mainly
> related to Java 8 and older versions. Thus I would appreciate it if you
> could clarify the followings:
> 
>> Loading all of Log4j’s plugins via ServiceLoader would be very slow
> 
> What kind of measurements and benchmarks show that? I have never had any
> issue with speed using ServiceLoader, as it is a standard way to load
> classes and get their objects which may not be there during the compile
> time. For example, my Jamal macro language loads all the macros and
> debuggers as services.
> SLF4J relies on ServiceLoader.

From this it is clear that you completely misunderstand what the plugin system 
is doing.
First, the plugin system DOES use ServiceLoader. In fact, Log4j uses 
ServiceLoader 
in at least 7 different places. For one, it uses ServiceLoader to locate the 
Log4j 
implementation similar to how SLF4J does (although Log4j implemented it prior 
to SLF4J).

Consider that you have 150 or so plugins, of which maybe only 10 will get used. 
But 
you don’t know beforehand which 10. ServiceLoader would have to load all 150 
classes. 
This is indeed very slow. Yes we have benchmarked it. But the Plugin system IS 
a 
Java Service. So instead, you need to only load 1 class for every jar that 
contains plugins. 
The result is that you only need to load 4 or 5 classes. This is considerably 
faster.

In addition, services loaded by ServiceLoader are singletons. It is not unusual 
to require 
multiple instances of.a Plugin so this would be difficult to do with the 
ServiceLoader. 
But since the service loaded for the plugin system only contains the plugin 
definition 
this is not an issue.

> 
>> and would require every
>> plugin be listed in the service configuration file.
> 
> I do not understand what configuration file you are talking about.

META-INF/services/service.fully.qualified.class.name. Every plugin would need 
an 
entry in this file if every Plugin is a raw service. In addition, for JPMS they 
would need 
an additional entry in module-info.java. The Log4j annotation processor 
generates the 
META-INF/services file for you. 

> 
> You implement an interface when you develop a service to be loaded by the
> JDK ServiceLoader. In addition to that, you either list the full name of
> the class in a text file inside your library, and the name of the file is
> the fully qualified name of the interface (this is the old style,
> pre-Java-9, and Java module systems), or you declare your service in the
> module-info.java file.

I’m not sure why you are explaining how ServiceLoader works. As I said, I am 
quite 
familiar with it.


> 
>> This has several problems:
>> 1. A service must have a constructor that accepts no parameters.
> 
> You can also have a provider method in the service implementing class.
> There is some flexibility introduced in Java 9.

Nothing that helps. What ServiceLoader really does best is instantiating 
factories. 
You then use that factory to instantiate what you really want. Most uses of 
ServiceLoader 
in Log4j do that.

> 
>> 2. Manually configuring every plugin in the META-INF/services file would
> be painful.
> 
> This is opinionated. There is no point debating opinions.

This is not opinion. This is a fact. Adding 50 entries to the service loader 
file is much 
more painful than adding just 1. There is no way you can argue against that.

> Editing a text
> file and inserting the name of the fully qualified name of the class never
> felt painful significantly since editors like IntelliJ help you copy/paste
> the fully qualified names. If you find it cumbersome to maintain these
> files manually, you can also use annotation processors to generate them. I
> have never used it, but Spring @AutoService does something like that.
> 
> In addition to that, you do not need to have the old-style
> META-INF/services files if you use Java 9 or newer.

That is not correct. That may be true when using the module path but the 
javadoc 
for ServiceLoader is quite clear that the file is still required for jars on 
the classpath. 
Since the vast majority of Java users do not use JPMS this isn’t really 
helpful. I 
should also note that in fact the opposite is true. If your jar is an automatic 
module 
then JPMS will create the provides statement for you based on the presence of 
the 
META-INF/services file.

> 
>> 3. Every plugin might have its own unique configuration. ServiceLoader
> provides no mechanism
>> for configuration.
> 
> This is true, but other modules, like commons configuration, do. This is
> also discussed by others, so let's not focus on this one.
> 
> I know that there are areas for plugins, which are not supported by the JDK
> service loader mechanism, but I am skeptical that these can be implemented
> in a library in a general way. One example is the version negotiation,
> which is very much application-specific. Another one is suitability
> negotiation, when your application may face several implementations of the
> service and there is room only for one: the best fitting for the purpose.
> These are very much application-specific and there are no widely accepted
> industry best practice standards.

Again, I would suggest you look at the log4j-plugins implementation before 
making sweeping statements such as this.

Ralph


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org

Reply via email to