On Wed, 15 Sep 2021 06:11:23 GMT, Jaikiran Pai <j...@openjdk.org> wrote:

>> The commit in this PR implements the proposal for enhancement that was 
>> discussed in the core-libs-dev mailing list recently[1], for 
>> https://bugs.openjdk.java.net/browse/JDK-8231640
>> 
>> At a high level - the `store()` APIs in `Properties` have been modified to 
>> now look for the `SOURCE_DATE_EPOCH` environment variable[2]. If that env 
>> variable is set, then instead of writing out the current date time as a date 
>> comment, the `store()` APIs instead will use the value set for this env 
>> variable to parse it to a `Date` and write out the string form of such a 
>> date. The implementation here uses the `d MMM yyyy HH:mm:ss 'GMT'` date 
>> format and `Locale.ROOT` to format and write out such a date. This should 
>> provide reproducibility whenever the `SOURCE_DATE_EPOCH` is set. 
>> Furthermore, intentionally, no changes in the date format of the "current 
>> date" have been done.
>> 
>> These  modified `store()` APIs work in the presence of the `SecurityManager` 
>> too. The caller is expected to have a read permission on the 
>> `SOURCE_DATE_EPOCH` environment variable. If the caller doesn't have that 
>> permission, then the implementation of these `store()` APIs will write out 
>> the "current date" and will ignore any value that has been set for the 
>> `SOURCE_DATE_EPOCH` env variable. This should allow for backward 
>> compatibility of existing applications, where, when they run under a 
>> `SecurityManager` and perhaps with an existing restrictive policy file, the 
>> presence of `SOURCE_DATE_EPOCH` shouldn't impact their calls to the 
>> `store()` APIs.
>> 
>> The modified `store()` APIs will also ignore any value for 
>> `SOURCE_DATE_EPOCH` that  cannot be parsed to an `long` value. In such 
>> cases, the `store()` APIs will write out the "current date" and ignore the 
>> value set for this environment variable. No exceptions will be thrown for 
>> such invalid values. This is an additional backward compatibility precaution 
>> to prevent any rogue value for `SOURCE_DATE_EPOCH` from breaking 
>> applications.
>> 
>> An additional change in the implementation of these `store()` APIs and 
>> unrelated to the date comment, is that these APIs will now write out the 
>> property keys in a deterministic order. The keys will be written out in the 
>> natural ordering as specified by `java.lang.String#compareTo()` API.
>> 
>> The combination of the ordering of the property keys when written out and 
>> the usage of `SOURCE_DATE_EPOCH` environment value to determine the date 
>> comment should together allow for reproducibility of the output generated by 
>> these `store()` APIs.
>> 
>> New jtreg test classes have been introduced to verify these changes. The 
>> primary focus of `PropertiesStoreTest` is the ordering aspects of the 
>> property keys that are written out. On the other hand 
>> `StoreReproducibilityTest` focuses on the reproducibility of the output 
>> generated by these APIs.  The `StoreReproducibilityTest` runs these tests 
>> both in the presence and absence of `SecurityManager`. Plus, in the presence 
>> of SecurityManager, it tests both the scenarios where the caller is granted 
>> the requisite permission and in other case not granted that permission.
>> 
>> These new tests and existing tests under `test/jdk/java/util/Properties/` 
>> pass with these changes.
>> 
>> [1] 
>> https://mail.openjdk.java.net/pipermail/core-libs-dev/2021-August/080758.html
>> [2] https://reproducible-builds.org/specs/source-date-epoch/
>
> Jaikiran Pai has updated the pull request incrementally with one additional 
> commit since the last revision:
> 
>   - Clarify how overriden Properties#entrySet() method impacts the order of 
> stored properties
>   - Tests to verify subclasses of Properties

Changes requested by rriggs (Reviewer).

src/java.base/share/classes/java/util/Properties.java line 819:

> 817:      * <p>
> 818:      * If the {@systemProperty java.util.Properties.storeDate} is set and
> 819:      * is non-empty (as determined by {@link String#isEmpty()  
> String.isEmpty}),

"is set **on the command line** and non-empty"...

Following from a comment on the CSR, it should be clear that the property value 
used can only be set on the command line.

src/java.base/share/classes/java/util/Properties.java line 850:

> 848:      * the {@code entrySet} method and return a different {@code Set} 
> instance,
> 849:      * then the property list is written out in the iteration order of
> 850:      * that returned {@code Set}

Rewording a bit:

"The keys and elements are written in the natural sort order of the keys in the 
`Properties.entrySet` unless `entrySet` is overridden by a subclass to return a 
different instance."

"different instance" is a bit hard to implement given that entrySet() returns a 
new synchronized set each time.
typo: missing final "."

src/java.base/share/classes/java/util/Properties.java line 932:

> 930:             if (entries instanceof Collections.SynchronizedSet<?> ss
> 931:                     && ss.c instanceof EntrySet) {
> 932:                 entries = new ArrayList<>(entries);

>From the description referring to a 'different instance', I expected to see == 
>or != in this test.
Since Properties.entrySet() always returns a new synchronized set of a new 
EntrySet,
specifying that the underlying map is the same instance is more difficult.
Perhaps either the SynchronizedSet or the EntrySet instance could be cached and 
compared.

(typo: missing space after period... ".If yes")

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

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

Reply via email to