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


Reply via email to