On Wed, 2 Dec 2020 14:40:15 GMT, Jan Lahoda <jlah...@openjdk.org> wrote:

>> This pull request replaces https://github.com/openjdk/jdk/pull/1227.
>> 
>> From the original PR:
>> 
>>> Please review the code for the second iteration of sealed classes. In this 
>>> iteration we are:
>>> 
>>>     * Enhancing narrowing reference conversion to allow for stricter 
>>> checking of cast conversions with respect to sealed type hierarchies
>>> 
>>>     * Also local classes are not considered when determining implicitly 
>>> declared permitted direct subclasses of a sealed class or sealed interface
>>> 
>>>     * renaming Class::permittedSubclasses to Class::getPermittedSubclasses, 
>>> still in the same method, the return type has been changed to Class<?>[] 
>>> instead of the previous ClassDesc[]
>>> 
>>>     * adding code to make sure that annotations can't be sealed
>>> 
>>>     * improving some tests
>>> 
>>> 
>>> TIA
>>> 
>>> Related specs:
>>> [Sealed Classes 
>>> JSL](http://cr.openjdk.java.net/~gbierman/jep397/jep397-20201104/specs/sealed-classes-jls.html)
>>> [Sealed Classes 
>>> JVMS](http://cr.openjdk.java.net/~gbierman/jep397/jep397-20201104/specs/sealed-classes-jvms.html)
>>> [Additional: Contextual 
>>> Keywords](http://cr.openjdk.java.net/~gbierman/jep397/jep397-20201104/specs/contextual-keywords-jls.html)
>> 
>> This PR strives to reflect the review comments from 1227:
>>  * adjustments to javadoc of j.l.Class methods
>>  * package access checks in Class.getPermittedSubclasses()
>>  * fixed to the narrowing conversion/castability as pointed out by Maurizio
>
> Jan Lahoda has updated the pull request incrementally with one additional 
> commit since the last revision:
> 
>   Improving Class.getPermittedSubclasses to filter out permitted classes that 
> are not a subtype of the current class, and other adjustments per the review 
> feedback.

I approve this version of `Class::getPermittedSubclasses` implementation for 
this PR.    We need to follow up the specification of 
`Class::getPermittedSubclasses` w.r.t. what it should return e.g. the classes 
whatever in `PermittedSubclasses` attribute vs the classes that are permitted 
subtypes at runtime and return null if this class is not sealed. 

I reviewed hotspot and java.base changes (not langtools) with a couple minor 
comments.

test/jdk/java/lang/reflect/sealed_classes/TestSecurityManagerChecks.java line 
51:

> 49: public class TestSecurityManagerChecks {
> 50: 
> 51:     private static final ClassLoader OBJECT_CL = 
> Object.class.getClassLoader();

This is `null` - the bootstrap class loader.   An alternative to the static 
variable we can simply use null.

test/jdk/java/lang/reflect/sealed_classes/TestSecurityManagerChecks.java line 
66:

> 64:                                                     .getProtectionDomain()
> 65:                                                     .getCodeSource()
> 66:                                                     .getLocation();

This is essentially the classpath.   An alternative way to get the location 
through `System.getProperty("test.class.path")`.

test/jdk/java/lang/reflect/sealed_classes/TestSecurityManagerChecks.java line 
86:

> 84: 
> 85:         // First get hold of the target classes before we enable security
> 86:         Class<?> sealed = 
> testLayer.findLoader("test").loadClass("test.Base");

I would recommend to use `Class::forName` instead of `ClassLoader::loadClass`  
even though this is just a test (for security reason for example avoid type 
confusion).   If you want to load a class from a specific module, you can use 
`Class.forName(String cn, Module m)`

test/jdk/java/lang/reflect/sealed_classes/TestSecurityManagerChecks.java line 
91:

> 89:         Class<?>[] subclasses = sealed.getPermittedSubclasses();
> 90: 
> 91:         if (subclasses.length != 3) {

I suggest to check against the expected list of permitted subclasses here and 
also the validation in the subsequent calls to `getPermittedSubclasses` with 
security manager enabled.   That would help the readers easier to understand 
this test.

test/jdk/java/lang/reflect/sealed_classes/TestSecurityManagerChecks.java line 
120:

> 118: 
> 119:         //should pass - does not return a class from package "test":
> 120:         sealed.getPermittedSubclasses();

Adding a check to the expected returned value would make this clear (no 
permitted subclasses of package `test`).

src/java.base/share/classes/java/lang/Class.java line 3035:

> 3033:      */
> 3034:     private static void 
> checkPackageAccessForPermittedSubclasses(SecurityManager sm,
> 3035:                                     final ClassLoader ccl, boolean 
> checkProxyInterfaces,

`checkProxyInterfaces` parameter is not needed.  It can be removed.

-------------

Marked as reviewed by mchung (Reviewer).

PR: https://git.openjdk.java.net/jdk/pull/1483

Reply via email to