I suspect at this point that most of the remaining slowness in startup
on Log4j is related to code that _doesn't_ use plugins. There are some
strategies that configure on startup in log4j-api based on system
properties and service loaders which are provided for improved
steady-state performance (or for garbage-free logging) but add
complexity to startup.

>From a DI point of view, I followed the standard @Inject style API
that projects such as Guice already use, though I included my own
copies of the javax annotations since we weren't relying on additional
dependencies there. In a generic plugins framework, this could be
abstracted further to support any general DI framework.

While the point of the plugin system is to be a much simpler approach
than something as complex as OSGi, it does seem like a valid concern
that it could become a sort of OSGi clone over time. With that in
mind, it becomes interesting to think what such a plugin system built
on top of OSGi would look like, though I haven't really explored that
possibility much (it was something I suggested long ago in the Jenkins
project as a way to improve and standardize their plugin system,
though there seems to be too much tech debt there to successfully do
so).

A potential design goal that could avoid OSGi-ifying the library would
be to aim to be a superfast, lightweight plugin system that can work
well with libraries, CLI apps (particularly interesting when using
GraalVM for AOT compilation or when using jlink/jpackage/etc. to
create a standalone application), and server software. If the DI
aspect is sufficiently pluggable, then that would allow for using
different DI backends appropriate to the target environment (e.g.,
using Spring in a long-running server app, or Avaje for a CLI app with
its code generation feature, or even the built-in DI impl for a
minimal-dependency library).

On Fri, Apr 8, 2022 at 2:38 AM Romain Manni-Bucau <rmannibu...@gmail.com> wrote:
>
> Guess that theorically there is room for a new generic plugin system but I
> would mention a few points:
>
> 1. log4j one is not yet a good *generic* one for multiple reasons but the
> biggest blocker for me is that it is slow (slower than a plain IoC as of
> today, even dropping some legacy parts) - there is a ticket about it but we
> are still slower than a plain CDI container even if it is way better than
> 2.x on 3.x branch
> 2. Most naturally you want your plugin system to integrate your IoC
> (spring, CDI, guice, ...) - to get injections, same bean pattern than your
> IoC/app, extensions, .... If we go with log4j system then we must do
> bridges which are quite useless in practise so it is an abstraction you
> will fight against instead of leveraging.
> 3. If there is a community around this project then it fits apache so it
> can go but I think it belongs better to incubator and not commons
>
> Hope it makes sense
>
> Romain Manni-Bucau
> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> <https://rmannibucau.metawerx.net/> | Old Blog
> <http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> |
> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
> <https://www.packtpub.com/application-development/java-ee-8-high-performance>
>
>
> Le ven. 8 avr. 2022 à 09:23, Peter Verhas <pe...@verhas.com> a écrit :
>
> > Thanks Ralph for the detailed explanation. I appreciate it and now I see
> > the points.
> >
> > I have never experienced an application where class loading time was an
> > issue, and I understand that it can really be.
> > I have never experienced a setup where there were a lot of "plugin" classes
> > on the classpath or on the modulepath that were never loaded by the
> > application.
> >
> > We still are not on the same page about module systems. I am happily using
> > it in all of my new projects and my experience is mixed. I accept the
> > struggle that it takes to make it properly, like opening the packaged via
> > command line options for testing purposes. On the other hand the structure
> > and the encapsulation is one step better than without JPMS.
> >
> > >But since you don’t want to look at he Log4j plugin system
> >
> > I did have a look at it to some level, as I also mentioned it  in my
> > previous mail. I am not an expert in that field as you are and I never
> > will, and that is what I do not want to be.
> >
> > I accept that there is room for a commons-plugin project. The project has
> > to address these questions to be on the right track (not to me, to the
> > project itself):
> >
> > - How will it be a "plugin" project and not another dependency injection
> > framework?
> > - What will distinguish it from module systems, like OSGi and what will
> > stop it from becoming another OSGi by the years as new features get added
> > to the library.
> > - What applications using plugins are the examples for different solutions?
> > (Log4j is a good example to show that there is a need, you also explained
> > patiently why it is not a simple ServiceLoader, but it is only one way to
> > solve it. Other applications may approach the issue differently. Maven,
> > Attlassian products, other build tools, JUnit 5 and so on.)
> > - Based on the gathered knowledge on the previous point, what is the high
> > level architecture of a plugin system the library will support and what
> > services will it provide?
> >
> >
> >
> >
> >
> > On Thu, Apr 7, 2022 at 7:57 PM Ralph Goers <ralph.go...@dslextreme.com>
> > wrote:
> >
> > >
> > >
> > > > On Apr 7, 2022, at 2:52 AM, Peter Verhas <pe...@verhas.com> wrote:
> > > >
> > > >
> > > >> I would suggest that before responding to this email that
> > > >> you go look at how log4j-plugins is implemented in the master branch.
> > > >>
> > > >
> > > > Sure, if you propose to create a commons-plugin library that is an
> > > extract
> > > > of the plugin handling of log4j so that log4j next releases do not need
> > > to
> > > > keep the functionality inside log4j but rather as a dependency on this
> > > new
> > > > library. On the other hand, if the goal is to create something that is
> > > > useful generally then we should look at other solutions as well.
> > >
> > > It remains to be seen whether Log4j would replace log4j-plugins with
> > > Commons-plugins. The point of looking at Log4j was to understand the
> > > problem it is solving and how it solves it.
> > >
> > >
> > > >
> > > >
> > > >> From this it is clear that you completely misunderstand what the
> > plugin
> > > >> system is doing.
> > > >>
> > > >
> > > > That may really be very much true.
> > > >
> > > >
> > > >> 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.
> > > >
> > > >
> > > > Not. It does not need to  create instances of all of them. This is
> > what I
> > > > explained, and this is the reason why I explained it. JPMS or not, the
> > > new
> > > > ServiceLoader used by Java 9 and later will call the static factory
> > > method
> > > > of the class if that exists. Then the plugin can decide if it wants
> > > itself
> > > > to be instantiated or not. Somewhere there should be some logic that
> > > > filters 10 from the 150. If that is in a central place implementing
> > some
> > > > industry-best-practice configuration based algorithm, or outsources the
> > > > decision to the plugins themselves should not make a big difference in
> > > > performance.
> > > >
> > > > On  the second though, instantiating 150 lightweight classes must not
> > be
> > > a
> > > > big burden. The ServiceProvider JavaDoc documentation suggest that
> > > services
> > > > should be implemented as proxies or factories instantiating their real
> > > > working class lazily in case the instantiation is costly.
> > >
> > > Class loading in general is slow. Perhaps not to you but we have
> > customers
> > > who
> > > complain about all the things we do during startup and locating and
> > > instantiating
> > > plugins is one of them. When we first switched to use the ServiceLoader
> > we
> > > attempted to load the plugin classes simply by having the plugin
> > > definition include
> > > the Class.Performance was very bad. We now only include the class name
> > and
> > > only access the Class when absolutely necessary.
> > >
> > > Again, if you think about what the Plugin Manager is doing, it is using
> > > ServiceLoader
> > > to find all Plugin Service instances. Each of these contains the
> > > definitions of all the
> > > plugins. The Plugin Manager then uses these to create the actual plugins.
> > > So in
> > > essence, the services are used as part of the factory. Note that
> > decisions
> > > about
> > > whether to load a plugin or not do not have to be made when the plugin
> > > service
> > > s accessed. That is deferred until the Plugin actually needs to be wired.
> > >
> > > >
> > > >
> > > >> 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.
> > > >>
> > > >
> > > > Yes, this is the approach where you insert another layer above the
> > > service
> > > > loader that does part of the job that the service loader can also do
> > in a
> > > > different way. Essentially you let the plugin libraries, each
> > containing
> > > > several plugin classes to implement their own service loaders.
> > >
> > > Sort of. With Log4j’s plugin system Plugins are not aware of
> > ServiceLoader
> > > at all. Other than that, it behaves the way you are describing.
> > >
> > > >
> > > >
> > > >> In addition, services loaded by ServiceLoader are singletons.
> > > >
> > > >
> > > > No, they are not. Every ServiceLoader instance will create new
> > instances,
> > > > and even a single ServiceLoader can be asked calling the `reload()`
> > > method
> > > > to evict the instances from its cache and create new instances.
> > >
> > > Umm. Even calling reload() doesn’t change it from being a singleton. You
> > > can
> > > only have a single instance at a time.
> > >
> > > Yes, I suppose if you use multiple ServiceLoader instances then you can I
> > > nstantiate multiple instances of the service. However, as you noted that
> > > wouldn’t
> > > be the best practice since the ServiceLoader really should be
> > > instantiating a
> > > factory that create as many instances as you want.
> > >
> > > >
> > > > Perhaps developing a commons-plugin system is a good point to require
> > > > application developers and plugin developers to use the module system.
> > >
> > > Please no. I would never encourage anyone to use it. It has caused
> > nothing
> > > but pain. Yes, that is opinion, but opinion based on experience.
> > >
> > > >
> > > >
> > > >> Again, I would suggest you look at the log4j-plugins implementation
> > > before
> > > >> making sweeping statements such as this.
> > > >>
> > > >
> > > > I am not an expert about log4j and the plugin system of it,which you
> > are.
> > > > From this distance it seems that log4j uses factories for the plugins
> > as
> > > > services or builders in case there is a need for some configuration. In
> > > > case of the builders the configuration parameters are injected that way
> > > > this plugin system implements a simple DI framework like Plexus, Pico,
> > > > Guava, Spring instead of using one. With the factory approach it does
> > the
> > > > same as the JDK ServiceLoader calling the `provider()` method.
> > > >
> > > > Again, if you find that answering the questions is difficult there may
> > be
> > > > several reasons. One thing is for sure: I am not trolling you. I am
> > > asking
> > > > these questions because I honestly believe that any new library should
> > > > address the things that are not addressed by other systems and
> > libraries,
> > > > and should provide a better way to do things, otherwise they will not
> > be
> > > > widely used.
> > >
> > >
> > > Frankly, I don’t think there is more to discuss. You asked why not just
> > > use
> > > ServiceLoader. But you have pretty much conceded that vanilla
> > > ServiceLoader
> > > by itself is not a good plugin system. You have agreed that using
> > > ServiceLoader
> > > to load factories is pretty much necessary. But since you don’t want to
> > > look at
> > > he Log4j plugin system to see how it makes creating plugins easy it is
> > > hard to
> > > discuss how it achieves the goals beyond just using ServiceLoader to load
> > > factories.
> > >
> > > Ralph
> > >
> > >
> > >
> > >
> > > ---------------------------------------------------------------------
> > > To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
> > > For additional commands, e-mail: dev-h...@commons.apache.org
> > >
> > >
> >
> > --
> > Peter Verhas
> > pe...@verhas.com
> > t: +41791542095
> > skype: verhas
> >

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

Reply via email to