> Note that all of this occurs ONLY because we are creating a test jar that will be used by other modules.
If it would simplify the build setup, why don't we migrate test-jars to their individual Maven modules? For instance, log4j-core and log4j-core-test, etc. On Tue, Apr 6, 2021 at 5:11 AM Ralph Goers <ralph.go...@dslextreme.com> wrote: > > > > On Apr 5, 2021, at 1:31 PM, Volkan Yazıcı <volkan.yaz...@gmail.com> > wrote: > > > >> ... this weird structure with two test source directories ... > > > > doesn't seem okay to me. Please, don't get me wrong. Not that I know of > > JPMS or anything, though this sttructure doesn't resemble anything I have > > ever seen. I don't want to believe that every major Java library with > JPMS > > support needs to have such ugly workarounds. Are we sure about this > > solution? Can we ask for a review from some other Apache fellow? (@Gary, > > how does Commons deal with this?) > > I’m not sure who you would want to ask. AFAIK Commons hasn’t tackled JPMS > yet and wouldn’t encounter this issue. The only person I can think of > would be Robert Scholte from the Maven project. He has worked closely with > the OpenJDK guys to have Maven support JPMS. > > That said, the problem is relatively simple. > Obviously, to create a JPMS module your code must have a module-info.java. > Once you do Maven requires that everything in the module be a JPMS module > - it looks for everything on the module path, not the class path. > Maven supports unit tests for JPMS modules by requiring that the test also > have a module-info.java that opens the same module as the corresponding > source. > Java annotation processors must be on the class path. > Log4j-api, Log4j-plugins and Log4j-core all publish test classes that > downstream modules use for testing. Things like the LoggerContextRule, > FileCleaner, etc. > Every JPMS module MUST have its own unique set of packages. > > All of these items cause some “interesting issues”. > The classes used for testing generally need to share the same package > space as the classes they are testing. This isn’t really legal but Maven’s > tooling allows it via the special module-info.java. It essentially creates > a new module with both the source and test in it as far as I can tell. > Because the unit tests use the same package as the thing they are testing > they cannot be package in a test jar for use by other modules. > The annotation processor has always had to be built by itself first, > before the full module it resides in. That has to be followed by another > compile to run the annotation processor to generate the Log4jPlugins.java > file, followed by another compile to compile all of it with the > Log4jPlugins class. > > So what you end up with is almost a script that has to be run > Compile the main code without its module-info.java file so that the test > classes can compile. > Compile the test classes that will be packaged in the test jar for other > modules to use. These classes will reside in the target/test-classes > directory. > Package the test jar. > Compile the main module-info.java. > Compile the unit tests - these will all go into the test-classes directory. > > At this point you can run the unit tests. If they pass the main jar is > created as normal. Both the test jar and main jar will be installed. > > Yes, this process could be done slightly differently. You could co-mingle > the classes destined for the test jar with the unit tests and compile them > all together. But then when you package the jar you would have to specify > every class to be included in it. I simply didn’t like that option and > chose to use the directory structure and build order to accomplish what is > needed. > > Note that all of this occurs ONLY because we are creating a test jar that > will be used by other modules. As I said, this jar cannot have any classes > in packages specified in the main module-info.java for the maven module. > “Normal” modules will have a src/main and src/test just as they always have > and both with have a module-info.java in them. > > > > > >> The test jars need to be installed in order for them to be used by the > > other log4j modules that follow. I see no reason they cannot be > published. > > They contain some useful stuff that others could use for unit testing if > > they wanted. > > > > I am really reluctant to make any internal goodie public without a > tangible > > use case and (preferably) user request, given the backward compatibility > > burden we will need to carry for a decade afterwards. > > > > First, we publish the test jars because they have to be installed to be > usable by downstream modules in Log4j. We have always published the test > jars as part of our release distribution. Maven does that by default. We > have never promised that they will remain compatible. > > Ralph