[
https://issues.apache.org/jira/browse/MCOMPILER-354?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16561270#comment-16561270
]
foo bar edited comment on MCOMPILER-354 at 7/30/18 9:17 AM:
------------------------------------------------------------
Mhhhh! I think I get it (but this still seems problematic to me: sounds like
test-scoped dependencies and whitebox tests can't work together):
* {{DoesntCompile}} is in an exported package
* It's method signature references a type of a non-exported package
* So javac warns me that it in unusable by any client
* {{Compiles}} compiles because it is not in an exported package so no such
check is done.
~
So let me see the implications of this.
Given a test {{T}} of a class {{C}}, if the following are both true:
* {{T}} is in the same package as {{C}} (this is the case of whitebox tests -
tests which exercise package-private classes and methods)
* {{C}} is in an exported package
Then to avoid the warning:
* {{T}} must only "visibly reference" classes of exported packages (eg. a
public/protected method argument or return type constitutes a visible
reference, while a private/package-private does not).
Indeed, if I ignore the warning, the support module compiles and runs, but the
client module doesn't compile since the test class in support is not visible.
~
To sum it up, the following circumstances can't work:
a/ modules {{lib}} and {{client}} are 2 maven and jigsaw modules. {{client}}
depends on {{lib}}
b/ class {{Clib}} in {{src/main}} of {{lib}} is in an exported package
c/ class {{Tlib}} in {{src/test}} of {{lib}} is in the same package as {{Clib}}
(eg. because it's a whitebox test who wants to test the package-private methods
of {{Clib}})
d/ {{Tlib}} references a class {{Tlibunex}} of an unexported package (ex: a
test support class) "in a visible way" (ex: as argument of a public method)
e/ {{Tclient}} in {{src/test}} of {{client}} depends on {{Tlib}}
--> Step e/ generates a compile error because {{Tlib}} references unexported
{{Tlibunex}} (javac just says it can't find {{Tlib}})
~
Makes sense, since:
* We want to run the test with the module system, just like in production
* Test classes patched into the module are indistinguishable from the main
classes.
*+_But _+*
* I have no way to export {{Tlibunex}} since it is in {{src/test}}, and
therefore not visible from {{module-info.java}} (it doesn't compile if I try to
export it) !
* So doesn't that mean that test-scoped dependencies and whitebox tests can't
work together? (if the test class references an unexported test-support class).
~
Also let's say that I change my perspective and consider my modules as fully
main + test modules. I tried that in branch {{ExportedTestPackages}}.
So now my modules export their test classes (at the cost of adding a ".test"
package in {{src/main}}, with an empty class, for each exported test package).
Now my module looks like:
{code:java}
module fr.cla.wires.support {
exports fr.cla.wires.support.functional;
exports fr.cla.wires.support.oo;
//Exported test packages to allow test-scoped-dependencies and
white-box-testing at the same time.
//It's a "main & test module", don't know yet if that pattern is acceptable.
exports fr.cla.wires.support.test.random.bools;
exports fr.cla.wires.support.test.random.vo;
exports fr.cla.wires.support.test.random.vo.types;
}
{code}
That could maybe be acceptable, even though I'm not sure this pattern is well
accepted.
But the classes in these test packages (eg. {{VoGenerator}}) reference the test
framework JunitQuickcheck.
So now I would have to export JunitQuickcheck packages from
{{module-info.java}}.
Thus I would need {{src/main}} to depend on JunitQuickcheck, which for sure is
not acceptable.
was (Author: vandekeizer):
Mhhhh! I think I get it (but this still seems problematic to me: sounds like
test-scoped dependencies and whitebox tests can't work together):
* {{DoesntCompile}} is in an exported package
* It's method signature references a type of a non-exported package
* So javac warns me that it in unusable by any client
* {{Compiles}} compiles because it is not in an exported package so no such
check is done.
~
So let me see the implications of this.
Given a test {{T}} of a class {{C}}, if the following are both true:
* {{T}} is in the same package as {{C}} (this is the case of whitebox tests -
tests which exercise package-private classes and methods)
* {{C}} is in an exported package
Then to avoid the warning:
* {{T}} must only "visibly reference" classes of exported packages (eg. a
public/protected method argument or return type constitutes a visible
reference, while a private/package-private does not).
Indeed, if I ignore the warning, the support module compiles and runs, but the
client module doesn't compile since the test class in support is not visible.
~
To sum it up, the following circumstances can't work:
a/ modules {{lib}} and {{client}} are 2 maven and jigsaw modules. {{client}}
depends on {{lib}}
b/ class {{Clib}} in {{src/main}} of {{lib}} is in an exported package
c/ class {{Tlib}} in {{src/test}} of {{lib}} is in the same package as {{Clib}}
(eg. because it's a whitebox test who wants to test the package-private methods
of {{Clib}})
d/ {{Tlib}} references a class {{Tlibunex}} of an unexported package (ex: a
test support class) "in a visible way" (ex: as argument of a public method)
e/ {{Tclient}} in {{src/test}} of {{client}} depends on {{Tlib}}
--> Step e/ generates a compile error because {{Tlib}} references unexported
{{Tlibunex}} (javac just says it can't find {{Tlib}})
~
Makes sense, since:
* We want to run the test with the module system, just like in production
* Test classes patched into the module are indistinguishable from the main
classes.
*+_But _+*
* I have no way to export {{Tlibunex}} since it is in {{src/test}}, and
therefore not visible from {{module-info.java}} (it doesn't compile if I try to
export it) !
* So doesn't that mean that test-scoped dependencies and whitebox tests can't
work together? (if the test class references an unexported test-support class).
> 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)