RFR: JDK-8216558: Lookup.unreflectSetter(Field) fails to throw IllegalAccessException for final fields

David Holmes david.holmes at oracle.com
Fri Jan 11 23:08:11 UTC 2019



On 11/01/2019 11:11 pm, Remi Forax wrote:
> 
> 
> ----- Mail original -----
>> De: "David Holmes" <david.holmes at oracle.com>
>> À: "Adam Farley8" <adam.farley at uk.ibm.com>, "core-libs-dev" <core-libs-dev at openjdk.java.net>
>> Envoyé: Vendredi 11 Janvier 2019 14:02:06
>> Objet: Re: RFR: JDK-8216558: Lookup.unreflectSetter(Field) fails to throw IllegalAccessException for final fields
> 
>> On 11/01/2019 10:46 pm, Adam Farley8 wrote:
>>> Hi All,
>>>
>>> I posit that you shouldn't be able to change the contents of a a final
>>> field.
>>
>> Nice in theory, but not true in practice.
>>
>>> However, if you use Field.setAccessible(true) before calling
>>> Lookup.unreflectSetter(Field), then you can get a MethodHandle that allows
>>> you to set the (reflected) value of a static final field.
>>>
>>> This seems wrong to me, so here's a change to fix it.
>>
>> See:
>>
>> https://docs.oracle.com/javase/10/docs/api/java/lang/reflect/Field.html#set(java.lang.Object,java.lang.Object)
>>
>> "If the underlying field is final, the method throws an
>> IllegalAccessException unless setAccessible(true) has succeeded for this
>> Field object and the field is non-static. Setting a final field in this
>> way is meaningful only during deserialization or reconstruction of
>> instances of classes with blank final fields, before they are made
>> available for access by other parts of a program. Use in any other
>> context may have unpredictable effects, including cases in which other
>> parts of a program continue to use the original value of this field. "
>>
>> the same semantics are supported by MH/VH.
> 
> No VH doesn't support setAccessible (don't ask me why) ...

I must correct myself. Of course MH and VH should not support 
setAccessible. MH and VH represent bytecode semantics and bytecode knows 
nothing about setAccessible.

That said bytecode semantics for final fields are tricky if strictly 
followed, as we should allow MH/VH to set a final field if called from 
the <clinit>/<init> of the target class - as that is what 
putfield/putstatic would do.

David
-----

> 
>>
>> But note this requires the field to be non-static - if you can set a
>> static final field this way then that may be a bug (they can still be
>> set via native methods of course).
>>
>> David
> 
> Rémi
> 
>> -----
>>
>>> webrev: http://cr.openjdk.java.net/~afarley/8216558/webrev/
>>> bug: https://bugs.openjdk.java.net/browse/JDK-8216558
>>>
>>> Opinions invited.
>>>
>>> Best Regards
>>>
>>> Adam Farley
>>> IBM Runtimes
>>>
>>> Unless stated otherwise above:
>>> IBM United Kingdom Limited - Registered in England and Wales with number
>>> 741598.
>>> Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU


More information about the core-libs-dev mailing list