ALL-UNNAMED module does not export all packages from classpath
Pavel Bucek
pavel.bucek at oracle.com
Mon Mar 20 22:44:02 UTC 2017
Hi Jon,
thanks. The credit goes to Libor, but he's not subscribed on these
mailing lists and I helped with the evaluation, so I know the issue we
faced.
What should we do now? Is reporting the issue here enough or should we
file an issue somewhere?
Regards,
Pavel
On 20/03/2017 23:31, Jonathan Gibbons wrote:
> Pavel,
>
> It looks like you have tripped over an issue in javac's handling of an
> automatic module, and its ability to read classes from the unnamed
> module (i.e. classpath).
>
> -- Jon
>
>
> On 03/20/2017 03:19 PM, Pavel Bucek wrote:
>> Hi Alex,
>>
>> The usecase is about compiling tests in maven projects.
>>
>> I mirrored the content of the zip to github:
>> https://github.com/pavelbucek/reproducer (project contains useful
>> README)
>>
>> The TestCase.java [1] contains simple testcase, compilable when
>> everything is on the classpath.
>>
>> When module-info.java is added to the standard sources of a maven
>> module, the compilation changes from "put everything on classpath" to
>> "put test dependencies on classpath, standard dependencies on module
>> path", which results in:
>>
>> javac -d target/test-classes -classpath
>> lib/junit-4.12.jar:lib/hamcrest-core-1.3.jar:lib/mockito-core-2.7.17.jar:lib/byte-buddy-1.6.11.jar:lib/byte-buddy-agent-1.6.11.jar:lib/objenesis-2.5.jar
>> --module-path target/classes -target 9 -source 9 -Xmodule:tst
>> --add-reads tst=ALL-UNNAMED src/test/java/tst/TestCase.java
>>
>> Test classes are effectively "patched" into main module (here called
>> "tst") and the module requires "ALL-UNNAMED", to be able to use test
>> dependencies.
>>
>> I'm not sure about exact cause, but seems like the ALL-UNNAMED module
>> doesn't automatically export all packages, only those which were
>> analyzed as required by some other module.
>>
>> When TestCase.java doesn't "import
>> org.mockito.stubbing.OngoingStubbing", classpath compilation is ok,
>> since we are not using that type directly. But it is part of the
>> fluent builder pattern, used on line 18 [2]. If there is a mechanism
>> which decides which package is required, it omitted the return type
>> of called "when" method, which caused the error. When the package is
>> explicitly imported, the error is gone and compilation proceeds as
>> expected.
>>
>> Regards,
>> Pavel
>>
>>
>> [1]
>> https://github.com/pavelbucek/reproducer/blob/master/src/test/java/tst/TestCase.java
>> [2]
>> https://github.com/pavelbucek/reproducer/blob/master/src/test/java/tst/TestCase.java#L18
>>
>>
>> On 20/03/2017 22:56, Alex Buckley wrote:
>>> I can't figure out which classes are on which path, and why you
>>> think ALL-UNNAMED should export FROM the classpath when its purpose
>>> is to export TO the classpath.
>>>
>>> Please clarify your configuration in a few short sentences, rather
>>> than asking us to open a zip file on an unknown host.
>>>
>>> Alex
>>>
>>> On 3/20/2017 2:44 PM, Pavel Bucek wrote:
>>>> // moving from jdk9-dev, as suggested.
>>>>
>>>> Hi Jon,
>>>>
>>>> Thanks for clarification of the error message.
>>>>
>>>> The main point here is that adding "import ... " fixes the issue,
>>>> which
>>>> doesn't feel correct.
>>>>
>>>> When dependencies are put on the classpath, the import statement is
>>>> not
>>>> required.
>>>>
>>>> Regards,
>>>> Pavel
>>>>
>>>> On 20/03/2017 22:26, Jonathan Gibbons wrote:
>>>>> If nothing else, the javac error message needs work.
>>>>>
>>>>>> (package org.mockito.stubbing is declared in module , which does not
>>>>>> export it)
>>>>>
>>>>> The space between "module" and "," means there's an "empty" module
>>>>> name there, for the unnamed module, which should have been stated
>>>>> explicitly (i.e. "declared in the unnamed module").
>>>>>
>>>>> Follow-ups would be better on jigsaw-dev or compiler-dev.
>>>>>
>>>>> -- Jon
>>>>>
>>>>>
>>>>>
>>>>> On 03/20/2017 02:15 PM, Libor Kramolis wrote:
>>>>>> Hello.
>>>>>>
>>>>>> I have problem to compile following unit test:
>>>>>> import org.junit.Test;
>>>>>> import static org.junit.Assert.assertEquals;
>>>>>> import static org.mockito.ArgumentMatchers.any;
>>>>>> import static org.mockito.Mockito.mock;
>>>>>> import static org.mockito.Mockito.when;
>>>>>>
>>>>>> public class TestCase {
>>>>>>
>>>>>> @Test
>>>>>> public void test() {
>>>>>> Context context = mock(Context.class);
>>>>>> when(context.test(any())) //returns
>>>>>> org.mockito.stubbing.OngoingStubbing
>>>>>> .thenReturn("mock");
>>>>>>
>>>>>> assertEquals("mock", context.test("any"));
>>>>>> }
>>>>>>
>>>>>> interface Context {
>>>>>> String test(String value);
>>>>>> }
>>>>>>
>>>>>> }
>>>>>> with following error:
>>>>>>
>>>>>> src/test/java/tst/TestCase.java:15: error:
>>>>>> OngoingStubbing.thenReturn(T,T...) in package
>>>>>> org.mockito.stubbing is
>>>>>> not accessible
>>>>>> .thenReturn("mock");
>>>>>> ^
>>>>>> (package org.mockito.stubbing is declared in module , which does
>>>>>> not export it)
>>>>>> where T is a type-variable:
>>>>>> T extends Object declared in interface OngoingStubbing
>>>>>> 1 error
>>>>>>
>>>>>> Interface org.mockito.stubbing.OngoingStubbing is returned by
>>>>>> when(…)
>>>>>> method. And whenever I explicitly import the interface (no other
>>>>>> change in code is necessary) compilation works.
>>>>>>
>>>>>> Full reproduced sources are available in zip file at
>>>>>> http://anise.cz/~paja/liba/reproducer.zip
>>>>>> <http://anise.cz/~paja/liba/reproducer.zip>. It contains javac
>>>>>> commands. It is also possible to build it by Maven.
>>>>>>
>>>>>> What do you think about this behaviour? It seems to me as a bug. The
>>>>>> import statement is very artificial in this case.
>>>>>>
>>>>>> Thanks in advance for your help.
>>>>>>
>>>>>> Best regards,
>>>>>> Libor
>>>>>
>>>>
>>
>
More information about the jigsaw-dev
mailing list