playframework / playframework

The Community Maintained High Velocity Web Framework For Java and Scala.
http://www.playframework.com
Apache License 2.0
12.55k stars 4.1k forks source link

EhCache with `diskPersistent=true` and Play 2.6.6 on development mode #7953

Open joantune opened 7 years ago

joantune commented 7 years ago

Play Version (2.6.6 )

API (Java / Both (?) )

Operating System (MacOS 10.11.6 )

JDK (Oracle 1.8.0_121-b13)

java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)

Expected Behavior & Actual behaviour

When having changes on the file, all classes should be ok, yet we have Class A cannot be cast into Class A because of EhCache using its own classloader

This is related with https://github.com/playframework/playframework/issues/6207

and https://github.com/playframework/playframework/issues/4159

if it's unavoidable, something should be added here or in a similar page: https://www.playframework.com/documentation/2.6.x/JavaCache

Also potentially with details for a good workaround i.e. have the cache in memory for development and using another ehcache in production, etc.

joantune commented 7 years ago

This issue is also solved by doing what is stated here:

https://www.playframework.com/documentation/2.6.x/JavaCache#Setting-the-execution-context

i.e. adding this:

play.cache.dispatcher = "contexts.blockingCacheDispatcher"

contexts {
  blockingCacheDispatcher {
    fork-join-executor {
      parallelism-factor = 3.0
    }
  }
}

to the config.

Some explicit reference to this issue in the documentation should be added, something like: if you want to user disk persistence you need to do this in order for the ~run to function properly WDYT?

wsargent commented 7 years ago

@joantune If it's EhCache calling Class.forName then there's not a lot that can be done on Play's end. Please provide stack traces and reproducible steps to help show what is happening.

joantune commented 7 years ago

@wsargent on a side not: the contexts setting seemed to fix the issue but it actually didn't, it apparently made it happen less often (??) as I made quite some changes and it didn't break.

@wsargent: yes they are, but we can do something like @mdii s suggestion here:

https://github.com/playframework/playframework/issues/6207#issuecomment-237003022

as a workaround, no?

benmccann commented 7 years ago

We should make sure to file a bug with EhCache if it's causing issues for Play users

joantune commented 7 years ago

@benmccann yeah, so, if my memory serves me right they use Class.forName at some point which they might always have to do when doing stuff like deserializing whole objects (??) most likely they serialize the classname and the contents or something similar (?) of the cache and deserialize it

as far as I understood, making sure that the Thread's classloader is Play's application one would solve this issue though, so we might just make sure that happens if the Class.forName is unavoidable.

Did I read this situation right @wsargent @jroper (I included J.Roper because most of these aforementioned conclusions were taken from his inputs on this issue: https://github.com/playframework/playframework/issues/4159)

benmccann commented 7 years ago

Yes, anything that uses Class.forName should take a classloader as a parameter so that we can pass in the appropriate one

joantune commented 7 years ago

Yes, so, after re-reading issue #4159 I went looking for a way to parameterize EhCache's classloader, and it appears that it's possible:

However you can still pass a specific ClassLoader to the CacheManager configuration. You can also give a specific ClassLoader per cache if you need to, taking precedence over the one configured at the CacheManager level. These will be used at runtime.

from: http://www.ehcache.org/documentation/3.4/class-loading.html