> On Jun 22, 2021, at 12:01 PM, Benjamin Marwell <bmarw...@apache.org> wrote:
> 
>> So now you would have a maven module with only the main source and no tests,
>> and a second module
>> where the “main” source is actually the test classes
>> and the unit tests test the code in a different Maven
>> module with a module info that opens the module-info of the main source jar.
>> Seems downright weird to me.
> 
> Well, it is not. First of all, you can test your main code nicely
> using standard non-modularized tests.
> No problem here.

Yes, there is a problem here. First, I am pretty sure that if I didn’t have a 
module-info.java file in my 
unit tests the build failed. Even if I could do that I wouldn’t be verifying 
that the module was constructed correctly.


> 
> Then you can use your module containing the abstract/common test
> classes with the scope <scope>test</scope>.
> This is actually what junit etc. is – you are using their main classes
> in YOUR test scope.
> So, nothing weird here, too.
> 
> The third project pulls them in altogether and is modularized.
> Call it "IT" or "integration test", and everything feels normal again.

So you would propose that any time someone wants to publish a test jar that 
they must have 3 Maven modules. 
Obviously I wouldn’t call it IT since it doesn’t contain integration tests, it 
contains unit tests. If I also had integration 
tests then I would need a fourth Maven module. That feels very “un-normal” to 
me. I don’t recall ever seeing a 
project that has the unit tests in a module separate from the main source.

It would make more sense to me to follow Robert’s suggestion of having the test 
jar and unit tests in a second 
module, but it feels strange that the unit tests in that module test the source 
from a different module. I haven’t tried, 
but I am also not sure if Maven will behave the same way when operating on a 
packaged jar as it does when the 
module-info.java for the unit tests extends the module-info for the main 
classes. I’d have to test that. I have a concern 
that it will think it is extending the test classes JPMS module.

I’ve also not tested a Maven module that has only unit tests. I suspect in that 
case it will not be possible to test the 
main source as a JPMS module since Maven seems to require a module-info.java in 
the main source before it 
will allow the unit tests to include one.

> 
> This will also help your IDE recognize the code.
> And as this is a common pattern, it will also help other coders to
> more easily recognize the structure of your project.

Yes, this will obviously make the IDE happier. I’m not sure about the 
developers though.

Ralph

> 
> Am Di., 22. Juni 2021 um 20:46 Uhr schrieb Ralph Goers
> <ralph.go...@dslextreme.com>:
>> 
>> Yes, you understand correctly. And yes, the test classes could be moved to a 
>> separate maven module, but
>> then the unit tests would also have to move as well as they are dependent on 
>> those test classes. Of course,
>> the test classes are dependent on the main source. As an example, log4j-core 
>> has a LoggerContext class,
>> the test jar has a LoggerContextRule class that uses the LoggerContext and 
>> the LoggerContextRule is used
>> by many unit tests.
>> 
>> So now you would have a maven module with only the main source and no tests, 
>> and a second module
>> where the “main” source is actually the test classes and the unit tests test 
>> the code in a different Maven
>> module with a module info that opens the module-info of the main source jar.
>> 
>> Seems downright weird to me.
>> 
>> Yes, I realize this doesn’t fit in the normal Maven lifecycle. I brought it 
>> up because if and/or when more
>> stuff starts becoming JPMS modularized this issue is going to become more 
>> and more common.
>> 
>> To be honest, I’d be OK living with the build the way it is except people 
>> are complaining that their IDE
>> has no idea what to do with the project.
>> 
>> Ralph
>> 
>>> On Jun 22, 2021, at 11:16 AM, 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
>> 
>> 
>> 
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscr...@maven.apache.org
>> For additional commands, e-mail: dev-h...@maven.apache.org
>> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscr...@maven.apache.org
> For additional commands, e-mail: dev-h...@maven.apache.org
> 
> 



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@maven.apache.org
For additional commands, e-mail: dev-h...@maven.apache.org

Reply via email to