JDK-8191112: javac OutOfMemoryError caused by "-Xlint:exports" option

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

JDK-8191112: javac OutOfMemoryError caused by "-Xlint:exports" option

Jan Lahoda
Hi,

Consider an automatic module "dep" with class "dep.Dep", and additional
automatic modules ext1 and ext2.

When javac has these on the modulepath, and compiles a module like this:
---
module mod {
     requires dep;
     exports api;
}

package api;

public class Api extends dep.Dep {}
---

-Xlint:exports can be used to report exported APIs that refer to types
potentially inaccessible to the clients. In this case, the supertype of
api.Api may be inaccessible unless the client has a dependency on "dep",
so the lint will warn about that. But since the dep, ext1 and ext2 are
automatic modules, each of the modules "requires transitive" the other
automatic modules, and the check may go into an infinite loop.

Moreover, for code like this:
---
module mod {
requires transitive ext1;
exports api;
}
---

"dep.Dep" is accessible using requires transitive edges of the automatic
modules, hence the warning/lint is not printed.

That does not seem quite right, an explicit "requires transitive dep"
dependency would be better, otherwise the changes in the module path can
lead to surprising behavior.

The suggested patch is to simply ignore the dependencies of automatic
modules in the check - that should avoid the infinite loop and print the
warning in the "requires transitive ext1" case.

Bug: https://bugs.openjdk.java.net/browse/JDK-8191112
Webrev: http://cr.openjdk.java.net/~jlahoda/8191112/webrev.00/

What do you think?

Thanks,
     Jan

Reply | Threaded
Open this post in threaded view
|

Re: JDK-8191112: javac OutOfMemoryError caused by "-Xlint:exports" option

Alex Buckley-3
On 11/14/2017 5:17 AM, Jan Lahoda wrote:

> ---
> module mod {
> requires transitive ext1;
> exports api;
> }
> ---
>
> "dep.Dep" is accessible using requires transitive edges of the automatic
> modules, hence the warning/lint is not printed.
>
> That does not seem quite right, an explicit "requires transitive dep"
> dependency would be better, otherwise the changes in the module path can
> lead to surprising behavior.
>
> The suggested patch is to simply ignore the dependencies of automatic
> modules in the check - that should avoid the infinite loop and print the
> warning in the "requires transitive ext1" case.

Good idea to make -Xlint:exports be more sophisticated w.r.t. automatic
modules ... but for the very last point, are you saying that a warning
is given for "requires transitive ext1" because of "transitive" or
because of "ext1"? That is, would a warning be printed for just
"requires ext1" ? I think it should be; the "transitive" in "requires
transitive ext1" is for the benefit of consumers of mod, which is not
germane to mod's barely-visible consumption of dep via ext1's implicit
"requires transitive dep1".

Alex
Reply | Threaded
Open this post in threaded view
|

Re: JDK-8191112: javac OutOfMemoryError caused by "-Xlint:exports" option

Jan Lahoda
Hi Alex,

On 14.11.2017 20:03, Alex Buckley wrote:

> On 11/14/2017 5:17 AM, Jan Lahoda wrote:
>> ---
>> module mod {
>> requires transitive ext1;
>> exports api;
>> }
>> ---
>>
>> "dep.Dep" is accessible using requires transitive edges of the automatic
>> modules, hence the warning/lint is not printed.
>>
>> That does not seem quite right, an explicit "requires transitive dep"
>> dependency would be better, otherwise the changes in the module path can
>> lead to surprising behavior.
>>
>> The suggested patch is to simply ignore the dependencies of automatic
>> modules in the check - that should avoid the infinite loop and print the
>> warning in the "requires transitive ext1" case.
>
> Good idea to make -Xlint:exports be more sophisticated w.r.t. automatic
> modules ... but for the very last point, are you saying that a warning
> is given for "requires transitive ext1" because of "transitive" or
> because of "ext1"? That is, would a warning be printed for just
> "requires ext1" ? I think it should be; the "transitive" in "requires
> transitive ext1" is for the benefit of consumers of mod, which is not
> germane to mod's barely-visible consumption of dep via ext1's implicit
> "requires transitive dep1".

(For completeness, there are other checks that inspect dependencies on
automatic modules, but this one is not specific to automatic modules, it
warns about using possibly inaccessible types in exported API.)

With the proposed patch, the warning would be printed for all "requires
transitive ext1", "requires ext1" and "requires dep", but not for
"requires transitive dep", as in the last case depending on "mod" will
make exported types from dep available to the client (which may be also
true for "requires transitive ext1", but that depends on how the module
path is constructed). If "ext1" would be an explicit module, which would
have "requires transitive dep", then the warning would not be printed
for "requires transitive ext1". If ext1 would contain only "requires
dep", then the warning would be printed.

Jan

>
> Alex
Reply | Threaded
Open this post in threaded view
|

Re: JDK-8191112: javac OutOfMemoryError caused by "-Xlint:exports" option

Alex Buckley-3
On 11/14/2017 11:16 AM, Jan Lahoda wrote:
> With the proposed patch, the warning would be printed for all "requires
> transitive ext1", "requires ext1" and "requires dep", but not for
> "requires transitive dep", as in the last case depending on "mod" will
> make exported types from dep available to the client ...

 > If "ext1" would be an explicit module, which would
> have "requires transitive dep", then the warning would not be printed
> for "requires transitive ext1".

 > If ext1 would contain only "requires
> dep", then the warning would be printed.

All sounds good!

Alex
Reply | Threaded
Open this post in threaded view
|

Re: JDK-8191112: javac OutOfMemoryError caused by "-Xlint:exports" option

Jonathan Gibbons
In reply to this post by Jan Lahoda
+1

-- Jon

On 11/14/2017 05:17 AM, Jan Lahoda wrote:

> Hi,
>
> Consider an automatic module "dep" with class "dep.Dep", and
> additional automatic modules ext1 and ext2.
>
> When javac has these on the modulepath, and compiles a module like this:
> ---
> module mod {
>     requires dep;
>     exports api;
> }
>
> package api;
>
> public class Api extends dep.Dep {}
> ---
>
> -Xlint:exports can be used to report exported APIs that refer to types
> potentially inaccessible to the clients. In this case, the supertype
> of api.Api may be inaccessible unless the client has a dependency on
> "dep", so the lint will warn about that. But since the dep, ext1 and
> ext2 are automatic modules, each of the modules "requires transitive"
> the other automatic modules, and the check may go into an infinite loop.
>
> Moreover, for code like this:
> ---
> module mod {
> requires transitive ext1;
> exports api;
> }
> ---
>
> "dep.Dep" is accessible using requires transitive edges of the
> automatic modules, hence the warning/lint is not printed.
>
> That does not seem quite right, an explicit "requires transitive dep"
> dependency would be better, otherwise the changes in the module path
> can lead to surprising behavior.
>
> The suggested patch is to simply ignore the dependencies of automatic
> modules in the check - that should avoid the infinite loop and print
> the warning in the "requires transitive ext1" case.
>
> Bug: https://bugs.openjdk.java.net/browse/JDK-8191112
> Webrev: http://cr.openjdk.java.net/~jlahoda/8191112/webrev.00/
>
> What do you think?
>
> Thanks,
>     Jan
>