You know, I almost didn’t want to answer this email because after reading the text it was quite obvious to me that the question you are really trying to ask is: “What more needs to be done to kill off 3.x?” That being said I will still answer your question.
First, I will say that the work to create module-info files in 2.x wouldn’t have been possible without all the effort put in to figure out how to separate the tests from the code. You have absolutely no idea how many hours I put in trying various permutations and asking around. Second, providing a module-info.class does not, in and of itself, make a library JPMS compliant. That is a requirement for it to be a named module, but it is only one facet of JPMS. Ask yourself, why was JPMS created? To allow Oracle to keep its JDK developers busy? No. The JDK had become bloated and even a simple HelloWorld app required the whole thing. Likewise, for a library like Log4j to depend on anything besides java.base will force the application to be bloated. Consider this (decompiled by IntelliJ - I am not really sure why none of them are listed as optional).: requires com.fasterxml.jackson.annotation; requires com.fasterxml.jackson.core; requires com.fasterxml.jackson.databind; requires com.fasterxml.jackson.dataformat.xml; requires com.fasterxml.jackson.dataformat.yaml; requires com.lmax.disruptor; requires disruptor; requires java.activation; requires java.base; requires java.compiler; requires java.desktop; requires java.logging; requires java.management; requires java.naming; requires java.rmi; requires java.scripting; requires java.sql; requires java.xml; requires javax.jms.api; requires javax.mail.api; requires jeromq; requires kafka.clients; requires org.apache.commons.compress; requires org.apache.commons.csv; requires org.apache.logging.log4j; requires org.codehaus.stax2; requires org.fusesource.jansi; requires org.jctools.core; requires org.osgi.core; With this: // Required Dependencies requires transitive org.apache.logging.log4j; requires transitive org.apache.logging.log4j.plugins; // Optional Dependencies requires static java.desktop; requires static java.management; requires static java.sql; requires static java.rmi; requires static java.xml; requires static com.lmax.disruptor; requires static org.jctools.core; requires static org.osgi.framework; requires static com.conversantmedia.disruptor; requires static com.fasterxml.jackson.core; requires static com.fasterxml.jackson.databind; requires static com.fasterxml.jackson.dataformat.xml; requires static com.fasterxml.jackson.dataformat.yaml; requires static org.apache.commons.compress; requires static org.fusesource.jansi; And even this list for 3.x is larger than we would like. I believe it has been identified how to eliminate all the java.* dependencies, but I would be surprised if even more of the non-java dependencies can be extracted. A lot of this was gained by splitting the modules in 3.x, which you admitted cannot be done in 2.x. Since that is one of the primary benefits of JPMS I am not sure how that makes 2.x better. Yes, we had to generate the module-info.java files by hand. Why? Because tooling didn’t exist. If it does now great1 But I am not sure why you are calling that out as if it is a negative thing. I mean, you still had to create the list of dependencies in the pom.xml by hand. What really is the difference? Next, there is a good chance that users really using JPMS won’t be able to access any plugins outside of log4j-core. See https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ClassLoader.html#getResource(java.lang.String). This is precisely why 3.x uses ServiceLoader to locate all plugins. So, while you may have successfully create module-info.class files was that a good thing? As an automatic module the rules in getResource() don’t apply. Next, Java supports ModuleLayers. See https://stackoverflow.com/questions/61195909/what-is-the-relation-between-modulelayer-and-classloader. If you get nothing out of this other than “it is complicated” that is enough. The bottom line here is again that you can’t rely on ClassLoader.getResource() to find plugins. As you may or may not have noticed, annotation processors cannot be located on the module path and must be strictly declared. In 2.x the processor is always included inside log4j-core. In 3.x it is simpler as it is its own module. Not necessarily a big deal but it provides better encapsulation. So is 2.x really the “clear winner”? I don’t think so, at least as far as JPMS is concerned. You haven’t even touched on the other benefits of 3.x . And the above hasn’t even touched on the other improvements in 3.x that are listed at https://logging.apache.org/log4j/3.x/, which unfortunately doesn’t call out the DI system Matt created (yet). Ralph > On Nov 6, 2023, at 2:02 PM, Volkan Yazıcı <vol...@yazi.ci> wrote: > > Could somebody help me to understand what we mean by JPMS support, please? > Because I have the impression that people think `2.x` does not have JPMS > support and `main` excels at it. > > `2.21.0` brought `2.x` a fully-fledged JPMS support. JPMS and OSGi > descriptors are auto-generated by `bnd-maven-plugin`. Piotr and I manually > marked every single package that needs to be exported and checked every > single generated `module-info.java` and `MANIFEST.MF`. IIRC, 3+ users > shared positive feedback in GitHub Issues and the next `2.x` release will > even support `jlink` due to #1896. Since there are no `module-info.java` > files lying around (`bnd-maven-plugin` adds them to the JAR at the > `package` phase), IDEs are not confused by the module-vs-class path dilemma > too. > > OTOH, JPMS support in the `main` branch was first established by > hand-written `module-info.java` files and then later on reimplemented (work > in progress!) by Piotr via porting stuff from `2.x`. Nobody has tested it > yet, AFAIK. `jlink` is known to not work there. > > In the context of JPMS support, `2.x` is a clear winner over `3.x`, AFAIC. > If not, I would appreciate your help in explaining what I am missing. > > Though `3.x` is good at two things regarding modularization: > > 1. It breaks down `log4j-core` into more fine-grained modules (e.g., > `log4j-csv`) > 2. It has slightly improved package encapsulation. That is, some > internal classes are indeed moved to internal packages. > > `2.x` can never implement #2, since it is a breaking change. Thought #1 can > very well be implemented for `2.x` – users will just need to add a new JAR > to their classpath.