[threeten-dev] Some observations of chrono ser
roger riggs
roger.riggs at oracle.com
Fri Mar 15 12:38:55 PDT 2013
Hi Sherman,
On 3/15/2013 3:08 PM, Xueming Shen wrote:
> The change itself looks fine for me, however I have couple more questions
> regarding the Chronology spec and implementation :-)
>
> (1) it appears, compared to Chronology.of(id), the
> Chronology.ofLocale(locale)
> has a slightly different implementation for looking up and loading, it
> stops after
> the look up of CHRONOS_BY_TYPE (built-in and application level service
> loader),
> while the Chronology.of(id) continues go on for the possible
> candidates from
> the ServiceLoad(contextClassLoader). Again, is this intended?
That is an oversight.
>
> (2) while I understand the intent of looking up a Chronology
> implementation
> via contextClassLoader, but it appears you can then pass around such a
> context
> specific Chronology (and probably the corresponding ChronoDate) around
> and
> to be shared beyond the original thread's "context", is this
> desirable? or we go
> with the enforcement of any Chronology is a global resource, need to
> be initialized
> via the application/system class loader?
With or without the help of Chronology an application can load
a Chronology via the ServiceLoader and it should be usable.
Regardless of where the application passes the reference it will
continue to provide it own implementations of the Chrono* interfaces.
Using the ContextClassLoader is a convenience and gives a consistent API for
locating Chronologies. Using the ContextClassLoader appears to be the
default for ServiceLoader.load so I don't see an issue there. Whether
a client or server, it should find the Chronology in the provided context.
Is there anything similar in other APIs; ResourceBundles for example?
Roger
>
> -Sherman
>
> On 03/15/2013 11:01 AM, roger riggs wrote:
>> Hi,
>>
>> Updated the webrev with removal of unnecessary/unused readResolve
>> methods,
>> reordered the Chronology.initCache method to ignore duplicate
>> Chronologies
>> from ServiceLoader.
>>
>> Webrev: http://cr.openjdk.java.net/~rriggs/webrev-serialization-283/
>>
>> Included a test fix for the JapaneseDate.of(1,1,1) problem.
>>
>> Roger
>>
>>
>> On 3/14/2013 9:07 PM, Roger Riggs wrote:
>>>
>>>>>>>
>>>>>>> On 3/12/2013 5:52 PM, Xueming Shen wrote:
>>>>>>>> Hi,
>>>>>>>>
>>>>>>>> (1) Chronology.writeReplace() is private, so the proxy Ser
>>>>>>>> mechanism
>>>>>>>> is actually disabled for all Chronology subclasses. Is it
>>>>>>>> intentional? Given
>>>>>>>> all JDK subclasses all have readResolve() defined (3 out of 4
>>>>>>>> to return
>>>>>>>> the singleton) I would assume the Ser delegation might not be
>>>>>>>> necessary,
>>>>>>>> though it might be still desirable to "enforce" the Ser pattern
>>>>>>>> here?
>>>>>>> Not quite, but still broken. The writeReplace method can be
>>>>>>> private but
>>>>>>> is used only if the Chronology class is Serializable.
>>>>>>> http://docs.oracle.com/javase/7/docs/platform/serialization/spec/output.html#5324
>>>>>>>
>>>>>>>
>>>>>>> The subclasses are serializable and that is triggering the
>>>>>>> default serialization.
>>>>>>>
>>>>>>> Is there an issue for this?
>>>>>>
>>>>>> I think a private writeReplace method don't have an effect on how
>>>>>> its serializable
>>>>>> subclass serializes itself. So I believe the existing 4 jdk
>>>>>> Chronology subclasses
>>>>>> are using the "jdk default mechanism" (not the Ser
>>>>>> delegation/proxy), so I was
>>>>>> asking if it is an intentional design/implementation. For any
>>>>>> other potential
>>>>>> user defined Chronology subclass, does the abstract Chronology
>>>>>> have anything
>>>>>> really need to be "serializable" and via the Ser mechanism? Two
>>>>>> possible designs
>>>>>> here
>>>>>>
>>>>>> (1) we want all the Chronology subclasses to be serialized via
>>>>>> "Ser" (then it can
>>>>>> be done via the Chronology.of(...) when read in), then the
>>>>>> writeReplace() probably
>>>>>> should be declared as non-private?
>>>>> The intent was that Chronology would always handle serialization
>>>>> and return the same (singleton) instances that are known to
>>>>> Chronology.
>>>>>
>>>>> To make that work the writeReplace method needs to be "protected
>>>>> final"
>>>>> and visible to subclasses and not be override-able.
>>>>>
>>>>
>>>> Something like the attached webrev?
>>>>
>>>> http://cr.openjdk.java.net/~sherman/jdk8_threeten/serChrono
>>> Yes, same as what I did.
>>>>
>>>> Do we really to make it "final" to enforce the abstract base class
>>>> Chronology to
>>>> always handle the serialization? Or be liberal to document that
>>>> this is encouraged,
>>>> but not enforced, with a "non-final" Chronology.writeReplace()
>>>
>>> I went with non-final because as final it would prevent subclassing
>>> a Chronology
>>> that had its own state to serialize, like the HijrahChronology that
>>> has variants.
>>> It seems inflexible to prevent that from anything but bundled
>>> Chronologies.
>>>>
>>>> Second question leads to my (2) in previous email. With the
>>>> enforcement of
>>>> Chronology.writeReplace()
>>>> ->Ser
>>>> ->Chronology.readExternal()
>>>> ->Chronology.of/of0(id)
>>>> ->cache.
>>>>
>>>> A Chronology instance may be serialized from a vm default impl to a
>>>> user-defined
>>>> Chronology in other vm, if there is overriding Chronology
>>>> implementation, however,
>>>> a built-in ChronoLocalDate, for example JapaneseDate, is always
>>>> hard-wired to the
>>>> built-in JapaneseChronology, so if you serialize and de-serialize a
>>>> JapaneseChronology
>>>> AND a JapaneseDate into other vm, you may get a user-defined
>>>> JapaneseChronology
>>>> and a built-in JapneseDate with bundled with a built-in
>>>> JapaneseChronology, something
>>>> undesired?
>>> I suppose there is little benefit from allowing the built-in
>>> chronologies to
>>> be overridden and it does open up some potential problems.
>>> To insure consistency, JapaneseDate could use
>>> Chronology.of("Japanese") to get
>>> the Chronology but that adds very little and will be slower.
>>>
>>> If we do away with the override then there should be at least a log
>>> message if the register of the ServiceLoader chronology fails.
>>>
>>> Also, note that the synchronization on whether initialization is
>>> complete
>>> is based on finding ISOChronology in the HashTable. That would need
>>> a different mechanism. (Its ok for multiple threads to do the init
>>> concurrently
>>> only one will win and it avoids a single threaded synchronization.)
>>>
>>> Roger
>>>
>
--
Thanks, Roger
Oracle Java Platform Group
Green Oracle <http://www.oracle.com/commitment> Oracle is committed to
developing practices and products that help protect the environment
More information about the threeten-dev
mailing list