Clojure

Add transient keyword to cached toString() value in _str

Details

  • Type: Defect Defect
  • Status: Open Open
  • Priority: Minor Minor
  • Resolution: Unresolved
  • Affects Version/s: Release 1.6
  • Fix Version/s: Release 1.7
  • Component/s: None
  • Labels:
  • Patch:
    Code
  • Approval:
    Incomplete

Description

_str field in Keyword and Symbol classes lazily caches result of toString(). Because this field is not transient, serializing (using Java serialization) any keyword before and after calling toString() for the first time yields different results:

(import (java.io ByteArrayOutputStream ObjectOutputStream
                 ByteArrayInputStream  ObjectInputStream))

(defn- serialize [obj]
  (with-open [bos (ByteArrayOutputStream.)
              stream (ObjectOutputStream. bos)]
    (.writeObject stream obj)
    (-> bos .toByteArray seq)))

(def s1 (serialize :k))
;(println :k)
(def s2 (serialize :k))
(println (= s1 s2))

Uncomment (println :k) and suddenly s1 and s2 are no longer equal.

This issue came up when I was trying to use keywords as key in [Hazelcast](https://github.com/hazelcast/hazelcast) map. Hazelcast uses serialized keys in various scenarios, thus if I first put something to map under key :k and then print :k, I can no longer find such key.

Patch: CLJ-1408-2.patch

Screened by:

  1. CLJ-1408.patch
    19/Apr/14 4:53 AM
    1 kB
    Tomasz Nurkiewicz
  2. CLJ-1408-2.patch
    09/May/14 3:55 PM
    1 kB
    Tomasz Nurkiewicz

Activity

Tomasz Nurkiewicz made changes -
Field Original Value New Value
Attachment CLJ-1408.patch [ 12955 ]
Alex Miller made changes -
Patch Code [ 10001 ]
Approval Triaged [ 10120 ]
Tomasz Nurkiewicz made changes -
Attachment CLJ-1408-2.patch [ 12975 ]
Rich Hickey made changes -
Approval Triaged [ 10120 ] Vetted [ 10003 ]
Rich Hickey made changes -
Fix Version/s Release 1.7 [ 10250 ]
Alex Miller made changes -
Approval Vetted [ 10003 ] Screened [ 10004 ]
Description {{_str}} field in {{Keyword}} and {{Symbol}} classes lazily caches result of {{toString()}}. Because this field is not {{transient}}, serializing (using Java serialization) any keyword before and after calling {{toString()}} for the first time yields different results:

{code}
(import (java.io ByteArrayOutputStream ObjectOutputStream
                 ByteArrayInputStream ObjectInputStream))

(defn- serialize [obj]
  (with-open [bos (ByteArrayOutputStream.)
              stream (ObjectOutputStream. bos)]
    (.writeObject stream obj)
    (-> bos .toByteArray seq)))

(def s1 (serialize :k))
;(println :k)
(def s2 (serialize :k))
(println (= s1 s2))
{code}

Uncomment {{(println :k)}} and suddenly {{s1}} and {{s2}} are no longer equal.

This issue came up when I was trying to use keywords as key in [Hazelcast](https://github.com/hazelcast/hazelcast) map. Hazelcast uses serialized keys in various scenarios, thus if I first put something to map under key {{:k}} and then print {{:k}}, I can no longer find such key.

Attaching patch against current master, will sign CLA if you agree with this issue.
{{_str}} field in {{Keyword}} and {{Symbol}} classes lazily caches result of {{toString()}}. Because this field is not {{transient}}, serializing (using Java serialization) any keyword before and after calling {{toString()}} for the first time yields different results:

{code}
(import (java.io ByteArrayOutputStream ObjectOutputStream
                 ByteArrayInputStream ObjectInputStream))

(defn- serialize [obj]
  (with-open [bos (ByteArrayOutputStream.)
              stream (ObjectOutputStream. bos)]
    (.writeObject stream obj)
    (-> bos .toByteArray seq)))

(def s1 (serialize :k))
;(println :k)
(def s2 (serialize :k))
(println (= s1 s2))
{code}

Uncomment {{(println :k)}} and suddenly {{s1}} and {{s2}} are no longer equal.

This issue came up when I was trying to use keywords as key in [Hazelcast](https://github.com/hazelcast/hazelcast) map. Hazelcast uses serialized keys in various scenarios, thus if I first put something to map under key {{:k}} and then print {{:k}}, I can no longer find such key.

*Patch:* CLJ-1408-2.patch

*Screened by:* Alex Miller - no test but not sure that's essential for this. If needed, can turn example here into a test.
Labels interop
Alex Miller made changes -
Approval Screened [ 10004 ] Incomplete [ 10006 ]
Description {{_str}} field in {{Keyword}} and {{Symbol}} classes lazily caches result of {{toString()}}. Because this field is not {{transient}}, serializing (using Java serialization) any keyword before and after calling {{toString()}} for the first time yields different results:

{code}
(import (java.io ByteArrayOutputStream ObjectOutputStream
                 ByteArrayInputStream ObjectInputStream))

(defn- serialize [obj]
  (with-open [bos (ByteArrayOutputStream.)
              stream (ObjectOutputStream. bos)]
    (.writeObject stream obj)
    (-> bos .toByteArray seq)))

(def s1 (serialize :k))
;(println :k)
(def s2 (serialize :k))
(println (= s1 s2))
{code}

Uncomment {{(println :k)}} and suddenly {{s1}} and {{s2}} are no longer equal.

This issue came up when I was trying to use keywords as key in [Hazelcast](https://github.com/hazelcast/hazelcast) map. Hazelcast uses serialized keys in various scenarios, thus if I first put something to map under key {{:k}} and then print {{:k}}, I can no longer find such key.

*Patch:* CLJ-1408-2.patch

*Screened by:* Alex Miller - no test but not sure that's essential for this. If needed, can turn example here into a test.
{{_str}} field in {{Keyword}} and {{Symbol}} classes lazily caches result of {{toString()}}. Because this field is not {{transient}}, serializing (using Java serialization) any keyword before and after calling {{toString()}} for the first time yields different results:

{code}
(import (java.io ByteArrayOutputStream ObjectOutputStream
                 ByteArrayInputStream ObjectInputStream))

(defn- serialize [obj]
  (with-open [bos (ByteArrayOutputStream.)
              stream (ObjectOutputStream. bos)]
    (.writeObject stream obj)
    (-> bos .toByteArray seq)))

(def s1 (serialize :k))
;(println :k)
(def s2 (serialize :k))
(println (= s1 s2))
{code}

Uncomment {{(println :k)}} and suddenly {{s1}} and {{s2}} are no longer equal.

This issue came up when I was trying to use keywords as key in [Hazelcast](https://github.com/hazelcast/hazelcast) map. Hazelcast uses serialized keys in various scenarios, thus if I first put something to map under key {{:k}} and then print {{:k}}, I can no longer find such key.

*Patch:* CLJ-1408-2.patch

*Screened by:*

People

Vote (0)
Watch (2)

Dates

  • Created:
    Updated: