Skip to content
This repository has been archived by the owner on Feb 9, 2019. It is now read-only.

Redis cache always uses Serializable/ObjectOutputStream #88

Open
aellerton opened this issue Sep 24, 2013 · 7 comments
Open

Redis cache always uses Serializable/ObjectOutputStream #88

aellerton opened this issue Sep 24, 2013 · 7 comments

Comments

@aellerton
Copy link

I am using the play redis cache to store Strings (JSON, actually).
I'd like those strings to be useful for non-Java applications but noticed that the cache always stores them as below:

redis 127.0.0.1:6379> get somekeyhere
"oos-rO0ABXQAgHsidHlwZSI6ImN1c3RvbWVyIiwidXNlcl91dWlkIjoiOGMxMzVjMDgtMjkzZi00NjQ3LTgyND98BjIiwiZW1haWwiOiJzYWxseUBjdXN0b21lci50ZXN0IiwiZGlzcGxheU5hbWUiOiJTYWxseSBCdXllciJ9"

Serializing direct to the cache (i.e. bypassing the redis plugin) works for strings no problem.

The code at https://github.com/typesafehub/play-plugins/blob/master/redis/src/main/scala/com/typesafe/plugin/RedisPlugin.scala shows the reason why: the type test is applied to Serializable first, so the test for String is never applied:

   if (value.getClass.isInstanceOf[Serializable]) {
      oos = new ObjectOutputStream(baos)
      oos.writeObject(value)
      oos.flush()
   } else if (value.getClass.isInstanceOf[String]) {
      dos = new DataOutputStream(baos)   // <-- NEVER GETS HERE!
      dos.writeUTF(value.asInstanceOf[String])
      prefix = "string"

The solution is to put the Serializable test at the end, after String, Int, Long, Boolean.

@salehsed
Copy link

Does it have any relation with getting objects out of cache ?

"play.api.cache.Cache.getAsUser"

warn] application - could not deserialize key ex:java.lang.ClassNotFoundException: models.User
java.lang.ClassNotFoundException: models.User

@aellerton
Copy link
Author

My version of play (2.1.3) doesn't have a getAsUser method. It has getAs[T] which is quite a lot more useful, I think.

In any case, the error you list is completely unrelated to the issue I've logged. Your issue is related to there being no models.User class found at runtime in your app.

The issue I've logged here is that serialization /does/ work with String (and objects), but with String it should write it directly as a string, not encode with an ObjectOutputStream.

@salehsed
Copy link

Thanks for the comment , Raised an issue for getAs
#89

@jroper
Copy link
Member

jroper commented Sep 27, 2013

A pull request that fixes this will most certainly be accepted.

@aellerton
Copy link
Author

No worries, I'll submit one to you soon. ..

@peter-fu
Copy link

The solution is to put the Serializable test at the end, after String, Int, Long, Boolean.

Agree.

Also, a data migration guide should be provided after this is fixed, because some Cache data are external and might be stored in redis via play-redis plugin.

@sunnykaka
Copy link
Contributor

This is still going on in 2.3.1, any solutions?

sunnykaka added a commit to sunnykaka/play-plugins that referenced this issue Apr 9, 2015
jroper added a commit that referenced this issue Apr 9, 2015
rmmeans pushed a commit to rmmeans/play-plugins that referenced this issue Jun 23, 2015
rmmeans pushed a commit to rmmeans/play-plugins that referenced this issue Jun 23, 2015
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants