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