Issue with qualified exports

Peter Levart peter.levart at gmail.com
Thu Jul 21 08:14:12 UTC 2016


Also,

While it is expected that qualified exports are mostly used among 
modules that are more tightly coupled and are therefore more likely 
compiled together, some tools that invoke compiler (for example Maven), 
have a strategy to compile one module at a time, incrementally building 
the artifacts as the dependency tree instructs (because they must insert 
other building steps before or after compilation of each module, such as 
generating sources, etc...).

So we have a problem here if such tool wants to 1st compile module A 
alone and then compile B which has a "requires" dependency on A, because 
A also has a qualified "export" dependency on B. An option like below 
could enable such separate compilation.

Regards, Peter


On 07/21/2016 10:05 AM, Peter Levart wrote:
> Hi,
>
> A "middle-ground" solution could be for javac to have yet another 
> option, for example:
>
>     --add-phantom-module=B
>
> Since the compiler invoker explicitly named the module, javac can 
> validate the qualified exports of other modules against this name too. 
> If both the exporting module declaration and the javac option have 
> miss-typed the name in the same way, so be it...
>
> Regards, Peter
>
>
> On 07/21/2016 01:40 AM, Paul Benedict wrote:
>> Thank you Alex. Sounds like good advice. I'll raise it over there. 
>> Thanks
>> for chatting with me about it.
>>
>> Cheers,
>> Paul
>>
>> On Wed, Jul 20, 2016 at 6:37 PM, Alex Buckley <alex.buckley at oracle.com>
>> wrote:
>>
>>> Since A does not require B, you are quite right that the compiler 
>>> doesn't
>>> need B to compile A per se. It's solely the qualified export to B that
>>> drives the compiler to demand B when compiling A's module 
>>> declaration. (I
>>> believe that javac should be disinterested in B when compiling A's type
>>> declarations.)
>>>
>>> By all means, raise an issue on jpms-spec-comments about how a 
>>> qualified
>>> export induces a compile-time circularity, being sure to note that 
>>> taking a
>>> more relaxed view means passing through garbage qualified exports.
>>>
>>> Alex
>>>
>>> On 7/20/2016 4:22 PM, Paul Benedict wrote:
>>>
>>>> Alex, I must respectfully disagree with your analogy. We both agree 
>>>> that
>>>> it is good for the compiler to check an "import" statement. I 
>>>> imagine we
>>>> would also both agree that checking "requires" is good too. I would
>>>> argue what makes this good is because the developer has the 
>>>> intention of
>>>> locating and consuming a resource -- package or module, respectively.
>>>> Even with a wildcard import statement, I am explicitly asking to 
>>>> consume
>>>> the contents of a package (whatever the contents); so if the package
>>>> isn't there, my intention cannot be met.
>>>>
>>>> However, in my scenario here, I have no need to consume. Module A 
>>>> is not
>>>> consuming anything from Module B. All I want to do is issue a 
>>>> directive
>>>> for Module B at runtime, if B is even available at runtime. So I don't
>>>> really think the analogy you gave me applies.
>>>>
>>>> Now, I could write a stub project for B and install it somewhere, but
>>>> that is kind of silly, don't you think? Why make me go through these
>>>> hoops? The compiler isn't providing any value here with this check. 
>>>> The
>>>> compiler doesn't need B to be statically accessible to prove anything
>>>> about exporting a package, does it? If it does, can you let me know 
>>>> why
>>>> it needs this proof?
>>>>
>>>> Cheers,
>>>> Paul
>>>>
>>>> On Wed, Jul 20, 2016 at 6:00 PM, Alex Buckley <alex.buckley at oracle.com
>>>> <mailto:alex.buckley at oracle.com>> wrote:
>>>>
>>>>      On 7/20/2016 3:07 PM, Paul Benedict wrote:
>>>>
>>>>          Currently I am writing a module that another team will 
>>>> consume.
>>>>          Let's just
>>>>          call these modules A and B. Module A must export its 
>>>> packages to
>>>>          Module B
>>>>          and B alone.
>>>>
>>>>          For reasons beyond my control, I do not have access to 
>>>> Module B.
>>>>          However, I
>>>>          don't need to consume any types from B or use B in anyway --
>>>>          just need to
>>>>          give package visibility to B. So the compiler is stopping me
>>>>          because it
>>>>          says "error: module not found". Yes, the compiler is right...
>>>>          but it's too
>>>>          right.
>>>>
>>>>          What do you think of loosening the compiler restriction 
>>>> here? I
>>>>          don't see a
>>>>          reason why the export target must be known at this point.
>>>>
>>>>
>>>>      We start by supposing that compile-time checking is good. 
>>>> Think of
>>>>      how the compiler checks your 'import' declarations in ordinary 
>>>> .java
>>>>      files. Even if you do a wildcard import because you're not sure
>>>>      which types you'll use, you still have the compiler checking that
>>>>      the package exists. For qualified exports, we assume that if 
>>>> you're
>>>>      friendly enough with the owner of B to add a qualified export 
>>>> to B,
>>>>      then you're friendly enough to have a copy of B available. As 
>>>> such,
>>>>      if you write 'exports ... to V' (yes, V, not B), then we aim to
>>>>      check that V exists. It doesn't, so you'll get an error, and 
>>>> you'll
>>>>      smack yourself for typing V rather than B.
>>>>
>>>>      A wrinkle in your scenario is that module B requires module A, 
>>>> so B
>>>>      must be compiled with A present. And, A must be compiled with B
>>>>      present, due to 'exports ... to B'. There's no circularity in the
>>>>      'requires' clauses, but there is effectively a circularity in the
>>>>      module declarations more broadly. A certain amount of incremental
>>>>      craftsmanship will be necessary to allow this pair of modules to
>>>> flower.
>>>>
>>>>
>>>>
>>>>
>>>>
>



More information about the jigsaw-dev mailing list