It feels to me like JPMS just plainly breaks the informal industry standard
of the Maven project layout we have all been using for a million years.

In addition, how is one supposed to test package private code if a test jar
tests a main jar where all packages are now different? This seems like a
problem whether the test code is in the same Maven module or not. Or am
I missing something? Am I the only one feeling like JPMS what developed in
a vaccum?

Gary


On Tue, Jun 22, 2021, 14:16 Robert Scholte <rfscho...@apache.org> wrote:

> If I understand correctly you want both log4j-core main classes and test
> classes be distributed as modularized jars.
> To me with JPMS you should move the modularized test-classes to a separate
> Maven module as a first citizen artifact.
> That should make it a lot easier.
> It should also make the separation more clear: classes under
> target/test-classes are there to unittest its main classes.
> Whereas this new module contains reusable (main) code for testing (which
> should be tested too ;) )
> I understand that this will change the GA(-classifier) for the testing
> module, but to me for a good reason.
>
> Even with your very small reduction of steps to simplify the process, it
> doesn't fit in the default lifecycle unless you write you introduce a new
> lifecycle-binding or write a new extension.
>
> Robert
>
> On 22-6-2021 07:02:59, Ralph Goers <ralph.go...@dslextreme.com> wrote:
> Sorry for posting again. I really need to proof-read better. Please ignore
> the prior email.
>
> I have recently had quite an adventure modifying several of Log4j’s Maven
> modules to
> implement JPMS on our master branch. It was an adventure due to a few
> issues:
>
> 1. https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8265826 .
> This bug has been fixed in Java 17 but Log4j uses Java 11 to build.
> 2. Log4j-plugins builds an annotation processor, packages it with the
> annotations
> and classes necessary to build and run plugins, creates and test jar and
> runs unit tests.
> 3. It is not possible to compile an annotation processor with a
> module-info.java present.
> The compile will fail because it can’t find the annotation processor
> “service” when
> compiling module-info.java.
> 4. It is very difficult to compile an annotation processor and then use it
> in the same Maven
> module. JPMS expects the annotation processor to either be on the
> classpath or specified
> with the processorpath option. When a module-info.java is present, Maven
> automatically
> moves everything to the module path. Maven only supports using coordinates
> to specify the
> processor path, which don’t exist when the processor is in the same
> module. The only way
> to solve this is to compile all the classes with proc=only without a
> module-info.java present.
> 5. Although number 4 might seem bad, it really doesn’t matter because
> javac will fail if a
> module-info.java is present because module-info.java will have a reference
> to the service
> class being generated by the annotation processor and for some reason
> module-info.java
> is resolved before the annotation processor runs.
> 6. If the main set of classes are compiled with a module-info.java every
> other compile
> in the Maven module must also be modularized. Likewise, if the main module
> does
> not contain a module-info.java no other compile can either.
> 7. JPMS requires that every module have its own package space with no
> overlap
> with any other JPMS module.
>
> So while generating the log4j-plugins module is quite painful, generating
> log4j-core isn’t
> much better. That is actually the primary focus for this list.
>
> Log4j-core consists of the main classes packaged in the jar, a test jar
> that is used by
> downstream Maven modules, and the unit tests. Prior to JPMS one would just
> create
> the main jar and then package all the test classes and unit tests in a
> test jar. This can
> no longer be done with JPMS.
>
> When a project publishes a test jar along with the main jar, just like any
> other JPMS
> module. the test jar cannot use the package space of the main classes.
> Log4j core
> uses org.apache.logging.log4j.core so I placed all the test utility
> classes under
> org.apache.logging.log4j.core.test. However, the unit tests all need to be
> packaged
> in the main package space since its module-info.java “extends” the main
> module and
> several unit tests are required to be in the same main package so that
> they can access
> package private methods specifically provided for testing.
>
> In order to get this to work I had to perform the following steps:
>
> • Compile all the main classes except module-info.java with the Plugin
> annotation processor.
> • Compile the main module-info.java.
> • Compile the test classes used by other modules with module-info.java and
> using the plugin preprocessor.
> • Package these test classes in a test jar.
> • Delete the module-info and generated source for the test classes.
> • Move the main module-info to a temp location.
> • Compile the unit test classes without module-info.java.
> • Move the main module-info back to the classes directory.
> • Compile module-info.java for unit tests.
> • Run the unit tests.
> • Create the main jar if the unit tests pass.
>
> Were it not for JDK-8265826 I believe this could have been simplified
> somewhat to:
>
> • Compile all the main classes except module-info.java with the Plugin
> annotation processor.
> • Compile the main module-info.java.
> • Compile the test classes used by other modules with its module-info.java
> and
> using the plugin preprocessor.
> • Package these test classes in a test jar.
> • Delete the module-info and generated source for the test classes.
> • Compile the unit test classes with its module-info.java.
> • Compile module-info.java for unit tests.
> • Run the unit tests.
> • Create the main jar if the unit tests pass.
>
> So the gist of this entire email is pretty simple. Is there a way Maven
> could be modified
> to better support creating test jars with JPMS?
>
> Ralph

Reply via email to