JDK-8059361 : (spec) Properties.stringPropertyNames() returns a set inconsistent with the assertions from the spec
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util
  • Affected Version: 9
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2014-09-29
  • Updated: 2019-11-29
  • Resolved: 2016-06-01
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9 b122Fixed
Related Reports
Relates :  
Relates :  
Description
Specification 
http://docs.oracle.com/javase/8/docs/api/java/util/Properties.html#stringPropertyNames--
says:

"The returned set is not backed by the Properties object. Changes to this Properties are not reflected in the set, or vice versa."

The "vice versa" part assumes that the returned set could be changed. In fact the returned instance throws UnsupportedOperationException for an attempt to add anything. The specification needs to be updated/clarified.

Please see the following code:

public class PropNames {
    public static void main(String[] args) {
        new java.util.Properties().stringPropertyNames().add("abc");
    }
}


The output will be

Exception in thread "main" java.lang.UnsupportedOperationException
	at java.util.AbstractCollection.add(AbstractCollection.java:262)
	at java.util.Collections$SynchronizedCollection.add(Collections.java:2035)

This doesn't look perfectly complying to the assertions from the spec

The following JCK9 test based on the current spec will fail due to this:
api/java_util/Properties/autd2.html#StringPropertyNames[changesAreNotReflectedInTheProperties]

Comments
Reconsidering this approach per request from Mandy.
26-05-2016

Review thread: http://mail.openjdk.java.net/pipermail/core-libs-dev/2016-May/041480.html Recommendation: the test should be changed to allow UnsupportedOperationException to be thrown from a modification attempt. If a modification attempt succeeds, the test should further check that the original Properties object is unaffected.
26-05-2016

The original: "The returned set is not backed by the Properties object. Changes to this Properties are not reflected in the set, or vice versa." I guess the point is that "vice versa" implies that the returned set is fully modifiable, which it isn't. An alternative: "The returned set is not backed by the Properties object. Changes to this Properties are not reflected in the returned set. Any changes made to the returned set are not reflected in this Properties object." I think "any changes" is indefinite regarding whether and what kind of modifications are allowed on the returned set. If the indefiniteness isn't definite enough, then perhaps this: "The returned set is not backed by the Properties object. Changes to this Properties are not reflected in the returned set. If the returned set allows modification, any modifications to the returned set are not reflected in this Properties object."
13-05-2016

It's true that elements cannot be added to the Set returned from Properties.stringPropertyNames(). However, that Set can be modified by any method that removes elements. The returned Set is from Hashtable.keySet(), for which this behavior is specified. It's not *specified* that the returned Set has these behaviors, though. Consider the following code: public static void main(String[] args) { Properties props = new Properties(); props.setProperty("abc", "123"); props.setProperty("def", "456"); Set<String> names = props.stringPropertyNames(); System.out.printf("stringPropertyNames=%s names=%s%n", props.stringPropertyNames(), names); names.remove("abc"); System.out.printf("stringPropertyNames=%s names=%s%n", props.stringPropertyNames(), names); props.setProperty("ghi", "789"); System.out.printf("stringPropertyNames=%s names=%s%n", props.stringPropertyNames(), names); } produces the output: stringPropertyNames=[abc, def] names=[abc, def] stringPropertyNames=[abc, def] names=[def] stringPropertyNames=[abc, def, ghi] names=[def] which shows that the returned Set is modifiable and that modifications to either does not affect the other, in accordance with the spec. So in fact the returned Set *is* modifiable, although adding elements is not permitted. This is perhaps surprising but it doesn't seem to be a spec violation to me. The spec could be updated to specify the exact behavior, but I think that would be overspecification. I could imagine that a future change might want to make the returned set entirely unmodifiable or even fully modifiable. I could imagine the spec might be modified thus: Changes to this Properties object are not reflected in the returned set. The returned set might or might not support allow modification operations. If the returned set is modified, such changes are not reflected in this Properties object.
14-10-2014