JDK-8247868 : com.sun.jdi.ObjectReference::setValue should throw InvalidTypeException for non-modifiable final fields
  • Type: Bug
  • Component: core-svc
  • Sub-Component: debugger
  • Affected Version: 15
  • Priority: P3
  • Status: Resolved
  • Resolution: Not an Issue
  • Submitted: 2020-06-18
  • Updated: 2022-01-27
  • Resolved: 2022-01-27
Related Reports
Relates :  
Relates :  
Relates :  
Description
Static final fields are non-modifiable via java.lang.reflect.Field::set.
In JDI, ObjectReference::setValue throws IllegalArgumentException if the given Field is static final field (see ReferenceTypeImpl::validateFieldSet)

Non-static final fields in a hidden class are non-modifiable via java.lang.reflect.Field::set.
ObjectReference::setValue should respect the spec of Field::set that ObjectReference::setValue can change the value of a given Field if it is modifiable.

It's unclear if the spec of ObjectReference::setValue should clarifiy the behavior regardless of the value of the accessible flag of the given Field.
Comments
After some discussion looks like the bug is about consistency between com.sun.jdi.ObjectReference::setValue() and java.lang.reflect.Field::set() Going to update the description to make it clearer
27-01-2022

From the spec of java.lang.reflect.Field::set(): ------------ If the underlying field is final, this Field object has write access if and only if the following conditions are met: setAccessible(true) has succeeded for this Field object; the field is non-static; and the field's declaring class is not a hidden class; and the field's declaring class is not a record class. If any of the above checks is not met, this method throws an IllegalAccessException. 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. ------------ Setting a final field is a very specific task which is out of scope for JDI. Current JDI behavior (don't allow to set any final fields) looks reasonable. Closing this bug as "not an issue", will file a bug for ObjectReference.setValue spec
27-01-2022

The spec says: -------- Sets the value of a given instance or static field in this object. The Field must be valid for this ObjectReference; that is, it must be from the mirrored object's class or a superclass of that class. If static, the field must not be final. ------- "If static" is confusing here. I think it should be "The field must not be final." ------- Throws: IllegalArgumentException - if the field is not valid for this object's class. InvalidTypeException - if the value's type does not match the field's type. ------- There is no mention about unmodifiable fields, but IllegalArgumentException looks more appropriate (and JDI throws it for final fields historically)
24-01-2022

Not sure I understand what is the bug about. Did some testing, results for regular and hidden classes are the same: static fields, instance fields: ObjectReference.setValue succeeded static final , instance final: ObjectReference.setValue fails with IllegalArgumentException: Cannot set value of final field
24-01-2022

Investigated and decided to move this issue to 19. Need to prepare some test coverage to better understand this.
06-12-2021

Targeting to 17.
04-11-2020