question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

NotSerializableException in AsyncCacheAPI#getOrElseUpdate

See original GitHub issue

Are you filing an issue? Please follow these checklists and provide us all the possible information to speed up the process.

Reporting a bug?

  1. Version of play-redis: 2.0.1
  2. Version of Scala: 2.12.4
  3. Version of Play: 2.6.6
  4. Describe the environment if applies (usually in cloud etc.) Local

So I was working on play-redis 1.6.1 but as soon as I migrated to 2.0.1 I faced two different problems using the method getOrElseUpdate.

When I use this method for the first time, they key is not found on redis, so the method does the update and store in redis before returning the value. The second time I ask for this key, I am getting the following error:

java.io.NotSerializableException: No configured serialization-bindings for class [java.lang.Object]
        at akka.serialization.Serialization.serializerFor(Serialization.scala:238)
        at akka.serialization.Serialization.$anonfun$deserialize$3(Serialization.scala:204)
        at scala.util.Try$.apply(Try.scala:209)
        at akka.serialization.Serialization.deserialize(Serialization.scala:204)
        at play.api.cache.redis.connector.AkkaDecoder.binaryToAnyRef(AkkaSerializer.scala:122)
        at play.api.cache.redis.connector.AkkaDecoder.$anonfun$stringToAnyRef$2(AkkaSerializer.scala:126)
        at scala.Function1.$anonfun$andThen$1(Function1.scala:52)
        at play.api.cache.redis.connector.AkkaDecoder.stringToAnyRef(AkkaSerializer.scala:126)
        at play.api.cache.redis.connector.AkkaDecoder.untypedDecode(AkkaSerializer.scala:113)
        at play.api.cache.redis.connector.AkkaDecoder.decode(AkkaSerializer.scala:97)

The second issue that I have is a problem that was solved on 1.6.1. Again, the java context is lost in getOrElseUpdate with the last version.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:1
  • Comments:10 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
KarelCemuscommented, Jan 17, 2018

It takes usually several hours to sync

1reaction
KarelCemuscommented, Jan 17, 2018

Great example, I reproduced the serialization issue. Unfortunately, I don’t know how to fix it right now. The issue lies in the Java erasure of runtime types and occurs only with Java version of AsyncCacheApi. More specifically, the issue is directly in Play, see the code. Here, Scala.classTag returns Object and I believe that’s due to runtime type erasure.

Explanation

When you miss on cache, you compute the actual value and then serialize it, which works as it asks the value itself for its type.

However, when you hit, it considers the ClassTag given by Scala.classTag, which is wrong.

In the previous version of Play, i.e., Play 2.5 and earlier, Play’s API didn’t support type parameter T and I used a workaround of caching besides the value also its type to be able to deserialize it later. However, since Play 2.6, I use this given type T, which works pretty well with the synchronous API, as the main type is not erased. But oviously, it doesn’t work with async API as CompletedStage<T> gets erased to CompletedStage<Object>.

So, it seems the issue is not in play-redis but I have to investigate it more to see how to deal with it.

Read more comments on GitHub >

github_iconTop Results From Across the Web

scala - NotSerializableException for `Map[String, String]` alias
The problem is that Map.mapValues produces an object that's not serializable. When alarms was created, it's run through something like alarms.
Read more >
DefaultAsyncCacheApi (Play 2.6.7)
Retrieve a value from the cache, or set it from a default Callable function. The value has no expiration. Specified by: getOrElseUpdate in...
Read more >
play.api.cache.AsyncCacheApi.getOrElseUpdate java code ...
return toJava( asyncCacheApi.getOrElseUpdate(key, intToDuration(expiration), Scala.asScalaWithFuture(block), Scala. classTag()));
Read more >
BlockManager - The Internals of Apache Spark
Cached blocks are blocks with non-zero sum of memory and disk sizes. ... If given key K is already in this map, getOrElseUpdate...
Read more >
Troubleshooting tips for java.io.NotSerializableException error ...
NotSerializableException message fills up log files when dynamic caching is enabled with diskoffload and/or cache replication is enabled.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found