Question about jdk.internal.HotSpotIntrinsicCandidate

Alex Buckley alex.buckley at oracle.com
Sat Dec 5 01:23:51 UTC 2015


On 12/2/2015 11:44 AM, Alex Buckley wrote:
> On 12/2/2015 2:16 AM, Stephane Epardaud wrote:
>> On 01/12/15 22:04, Alex Buckley wrote:
>>> There shouldn't be any surprise here. In Java SE 8, you can declare a
>>> package-private annotation type and use it to write annotations on
>>> public classes of that package. Going up a level in Java SE 9, you can
>>> declare a module-private annotation type (i.e. public @interface Foo
>>> in a non-exported package) and use it to write annotations on exported
>>> public classes of that module.
>>
>> But I thought that Java 9 would check that you can't export a type
>> outside the module without also exporting the types it exposes? Like
>> public method return and parameter types. Can't remember where I read
>> that, though… Is that planned or not?
>
> We have not yet determined whether it should be a JLS-specified
> compile-time error or a JLS-specified compile-time warning or a
> compiler-specific compile-time warning or nothing at all. If you have
> concrete experience wrangling a module's exports to support the module's
> signatures, please send to jpms-spec-comments.

I discussed this with Jon today, and we think a compiler-specific 
compile-time warning (i.e. a lint warning) is suitable.

It has always been possible to declare classes, fields, and methods 
whose signatures use "surprisingly" inaccessible types. For example, the 
declaration of public class StringBuilder extends a superclass 
AbstractStringBuilder that's inaccessible to most code, yet anyone can 
do new StringBuilder().

For this reason, we don't want a warning if an exported type in module M 
uses, somewhere in a public signature, a type _that's in M but not 
exported by M_.

We want a warning that's particular to the module system issue of types 
coming from other modules. That is, if an exported type in module M 
uses, somewhere in a public signature, a type _that's exported by 
another module_, then M should really say "requires public" to transmit 
readability of the other module to M's consumers. A lint warning should 
appear if M just "requires" the other module.

Some points:

- A "public signature" is the declaration of a public field, public 
method, or public constructor. The types "used" in a public signature 
are the type of the field, or any formal parameter type or return type 
of the method, or any formal parameter type of the constructor.

- Annotations play no part in this analysis. Their presence on a public 
field, public method, or public constructor (or in the case of type 
annotations: on a type used in a public signature) does not justify 
"requires public" because the majority of M's consumers don't care about 
annotations on M's code and so don't need to access the types of those 
annotations in the other module.

- A public signature might be declared in the exported type of module M, 
or it might be inherited from a supertype thereof. If the public 
signature belongs to an inherited member, then the lint warning should 
appear immediately before the { of the class body of the exported type.

- It may be that the other module employs a qualified export to export 
the type only to M and a handful of friends. That's fine -- M should 
still be saying "requires public". Then, every module that reads M will 
read the other module, but won't be able to access the type exported by 
the other module for use in M's public signature.

- The warning is not mandated in the JLS because M saying "requires" 
rather than "requires public" is NOT an issue that leads to a dangerous 
discrepancy between compile and run time. (In contrast, the JLS mandates 
"unchecked warnings" for scenarios where the compiler is aware of a loss 
of type safety but where the JVM will not be aware and so will silently 
pollute the heap.)

Alex


More information about the jigsaw-dev mailing list