[ 
https://issues.apache.org/jira/browse/MCOMPILER-354?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16561699#comment-16561699
 ] 
foo bar edited comment on MCOMPILER-354 at 7/30/18 1:49 PM:
------------------------------------------------------------

Ok, I think I managed to articulate what I want and what I think is the problem 
in a precise way.

I create a branch with just enough code to make it realistic, checkout branch 
{{ILLUSTRATE_TST_DEP_AND_WHITEBOX}}, try to do (2. Whitebox testing), and get 
the following error:
{code:java}
[WARNING] 
/G:/projets/wires/wires/wires/wires-support/src/test/java/fr/cla/wires/support/oo/Accumulable_PbtTest.java:[53,23]
 class fr.cla.wires.support.oo.ddd.support.pbt.VoPair in module 
fr.cla.wires.support is not exported
{code}



h1. What I want to achieve and why it doesn't work
In short, whitebox tests and test-scoped dependencies don't play nice together, 
because module patching exported packages pulls (potentially unexported) 
dependencies of the test to the module.

The perfect storm happens when 1. 2. 3. all happen:

1. Maven test-scoped dependencies
See 
{{MultipleAnd_ReduceAndCollectShouldBeEquivalent_PbtTest::should_give_same_result_when_inputs_are_all_set}}
 in {{src/test}} of {{fr.cla.wires.core}}:
I reuse test-support class {{@RandomBooleans}} from src/test}} of module 
{{fr.cla.wires.support}}.
To do this Maven will patch test classes into the module. Then these test 
classes are indistinguishable from a main class for the JPMS.

2. Whitebox testing
See 
{{Accumulable_PbtTest::if_newVal_is_not_null_mutableEquivalentToInitially_should_be_equivalent_to_initially}},
 in {{src/test}} of {{fr.cla.wires.support}}:

In the call {{acc.unsafeMutableEquivalentToInitially(initialAndNewValues.y);}}, 
I want to make {{unsafeMutableEquivalentToInitially}} package-private.

To do that I need to move {{Accumulable_PbtTest}} to the same package 
{{fr.cla.wires.support.oo}} as {{Accumulable}}

3. The whitebox test class references {{VoPair}} from unexported package 
{{fr.cla.wires.support.oo.ddd.support.pbt}} "in a visible way" (It has a public 
method that takes {{VoPair}} as an argument. No compiler error if the method is 
package-private, but then the test framework can't run the test)


4. The perfect storm
>From 1. + 2. + 3., the whitebox test class is in exported package 
>{{fr.cla.wires.support.oo}} of module {{fr.cla.wires.support}}, and references 
>an unexported package in a visible way.

I thus get a warning compiling {{fr.cla.wires.support}} then an error compiling 
{{fr.cla.wires.core}} because {{Accumulable_PbtTest}} is not usable by any 
class in another module.

h1. A limitation of module patching?

The problem is that:
* I didn't really want to export {{Accumulable_PbtTest}}
* The test dependency that I do need is {{@RandomBooleans}}

So then, is it right to say that this is a limitation of how Maven implements 
whitebox tests using module patching: module patching exported packages adds 
test dependencies to the expected dependencies.

The intention of the user is not to export the test packages into the same 
Jigsaw module as the production code. That is just how it's implemented. 

But then: 
* Could it be implemented differently in the future or is that impossible 
barring collaboration from the JPMS? (like differentiating tests in modules)
* Should this limitation at least not be documented explicitly? I'm sure many 
people will get trapped by this.



was (Author: vandekeizer):
Ok, I think I managed to articulate what I want and what I think is the problem 
in a precise way:

h1. What I want to achieve and why it doesn't work
In short, whitebox tests and test-scoped dependencies don't play nice together, 
because module patching exported packages pulls (potentially unexported) 
dependencies of the test to the module.

The perfect storm happens when 1. 2. 3. all happen:

1. Maven test-scoped dependencies
See 
{{MultipleAnd_ReduceAndCollectShouldBeEquivalent_PbtTest::should_give_same_result_when_inputs_are_all_set}}
 in {{src/test}} of {{fr.cla.wires.core}}:
I reuse test-support class {{@RandomBooleans}} from src/test}} of module 
{{fr.cla.wires.support}}.
To do this Maven will patch test classes into the module. Then these test 
classes are indistinguishable from a main class for the JPMS.

2. Whitebox testing
See 
{{Accumulable_PbtTest::if_newVal_is_not_null_mutableEquivalentToInitially_should_be_equivalent_to_initially}},
 in {{src/test}} of {{fr.cla.wires.support}}:

In the call {{acc.unsafeMutableEquivalentToInitially(initialAndNewValues.y);}}, 
I want to make {{unsafeMutableEquivalentToInitially}} package-private.

To do that I need to move {{Accumulable_PbtTest}} to the same package 
{{fr.cla.wires.support.oo}} as {{Accumulable}}

3. The whitebox test class references {{VoPair}} from unexported package 
{{fr.cla.wires.support.oo.ddd.support.pbt}} "in a visible way" (It has a public 
method that takes {{VoPair}} as an argument. No compiler error if the method is 
package-private, but then the test framework can't run the test)


4. The perfect storm
>From 1. + 2. + 3., the whitebox test class is in exported package 
>{{fr.cla.wires.support.oo}} of module {{fr.cla.wires.support}}, and references 
>an unexported package in a visible way.

I thus get a warning compiling {{fr.cla.wires.support}} then an error compiling 
{{fr.cla.wires.core}} because {{Accumulable_PbtTest}} is not usable by any 
class in another module.

h1. A limitation of module patching?

The problem is that:
* I didn't really want to export {{Accumulable_PbtTest}}
* The test dependency that I do need is {{@RandomBooleans}}

So then, is it right to say that this is a limitation of how Maven implements 
whitebox tests using module patching: module patching exported packages adds 
test dependencies to the expected dependencies.

The intention of the user is not to export the test packages into the same 
Jigsaw module as the production code. That is just how it's implemented. 

But then: 
* Could it be implemented differently in the future or is that impossible 
barring collaboration from the JPMS? (like differentiating tests in modules)
* Should this limitation at least not be documented explicitly? I'm sure many 
people will get trapped by this.


> Module patching fails: case of simple single-module project
> -----------------------------------------------------------
>
>                 Key: MCOMPILER-354
>                 URL: https://issues.apache.org/jira/browse/MCOMPILER-354
>             Project: Maven Compiler Plugin
>          Issue Type: Bug
>    Affects Versions: 3.7.0
>         Environment: $ mvn -version
> Apache Maven 3.5.4 (1edded0938998edf8bf061f1ceb3cfdeccf443fe; 
> 2018-06-17T20:33:14+02:00)
> Maven home: G:\software\apache-maven-3.5.4-bin\apache-maven-3.5.4
> Java version: 10.0.2, vendor: Oracle Corporation, runtime: C:\Program 
> Files\Java\jdk-10.0.2
> Default locale: fr_FR, platform encoding: Cp1252
> OS name: "windows 7", version: "6.1", arch: "amd64", family: "windows"
>            Reporter: foo bar
>            Priority: Major
>              Labels: Jigsaw
>         Attachments: mvn-X-clean-install-FAILURE.log, project.png, wires.zip
>
>
> Sometimes it can be difficult to setup maven test-scoped dependencies in a 
> Maven multi-module project. But I think I managed to find a simple 1-module 
> case where module patching doesn't work.
> I have a single-module Java 10 project where the testCompile goal complains 
> that Test Class A doesn't read Test Class B, which is in the same project! 
> (but in a different package)
> Of course, a class shouldn't need to be exported to a class of the same 
> module. So maybe there is a confusion somewhere between the unnamed module, 
> automatic modules, and explicit modules.
> I think that's because of a bug in the module-patching flags passed by 
> testCompile to javac.
> My project source tree, in its simplified branch to reproduce the issue, 
> looks shown in the project.png attachment.
> Full log is attached as well as a zip of the issue reproduction branch. It 
> can also be cloned from: 
> {code:java}
> git clone https://github.com/vandekeiser/wires.git
> git checkout REPORT-MCOMPILER-2
> mvn clean install
> {code}
> The flags testCompile pass to javac.
> {code:java}
> [INFO] --- maven-compiler-plugin:3.7.0:testCompile (default-testCompile) @ 
> wires-support ---
> [DEBUG] Command line options:
>     -d G:\projets\wires\wires\wires\wires-support\target\test-classes
>     -classpath G:\projets\wires\wires\wires\wires-support\target\test-classes;
>     --module-path G:\projets\wires\wires\wires\wires-support\target\classes;
>     -sourcepath G:\projets\wires\wires\wires\wires-support\src\test\java;
>                 
> G:\projets\wires\wires\wires\wires-support\target\generated-test-sources\test-annotations;
>     -s 
> G:\projets\wires\wires\wires\wires-support\target\generated-test-sources\test-annotations
>     -g -deprecation -target 10 -source 10 -encoding UTF-8 -Werror 
> -Xlint:all,-serial
>     --patch-module fr.cla.wires.support=
>         G:\projets\wires\wires\wires\wires-support\target\classes;
>         G:\projets\wires\wires\wires\wires-support\src\test\java;
>         
> G:\projets\wires\wires\wires\wires-support\target\generated-test-sources\test-annotations;
>     --add-reads fr.cla.wires.support=ALL-UNNAMED
> {code}
> The warning I get (which for me is an error):
> {code:java}
> [WARNING] 
> /G:/projets/wires/wires/wires/wires-support/src/test/java/fr/cla/wires/support/DoesntCompile.java:[14,20]
>     class 
> fr.cla.wires.support.javac_complains_this_is_not_exported.JavacComplainsThisIsNotExported
>     in module fr.cla.wires.support
>     is not exported
> [ERROR] COMPILATION ERROR :
> warnings found and -Werror specified
> [INFO] 1 error
> {code}



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to