To to that would require 2 test modules. The first would generate the test classes that are used by both the unit tests and downstream modules. The second would be the unit tests themselves.
However, I have doubts that that would work. As I said, Maven allows an essentially illegal module-info.java for unit tests. I’d have to try it of course, but I have my doubts that it would work if it was in a separate Maven module. Ralph > On Apr 8, 2021, at 7:51 AM, Volkan Yazıcı <volkan.yaz...@gmail.com> wrote: > >> 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