Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Class cast exception when deserializing in Spring #1

Open
danomatic opened this issue Mar 2, 2017 · 9 comments
Open

Class cast exception when deserializing in Spring #1

danomatic opened this issue Mar 2, 2017 · 9 comments

Comments

@danomatic
Copy link

When using @Cacheable in a ThreadPoolExecutor, the deserialize is failing. It looks like this:

java.lang.ClassCastException: com.company.SomeBean cannot be cast to com.company.SomeBean
	at com.company.services.SomeService$$EnhancerBySpringCGLIB$$a724921e.getData(<generated>)
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:720)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
	at org.springframework.aop.interceptor.AsyncExecutionInterceptor$1.call(AsyncExecutionInterceptor.java:115)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)

If I write a unit test that just calls the method outside of a thread pool, it seems to work. Do you have any idea why this would happen? Can this library use a custom serializer?

@dnlprplt
Copy link
Contributor

dnlprplt commented Mar 2, 2017

Can you please give us the signature of the method you put the @Cacheable on? As well as the params of the @Cacheable you used?

And if you can give us a unit test we can run, it would be even better.

@aymhce
Copy link

aymhce commented May 18, 2017

hello, i have the same issue

java.lang.ClassCastException: fr.***.digital.domain.***UserDetails cannot be cast to fr.***.digital.domain.***UserDetails
	at fr.***.digital.client.***ConnectClient$$EnhancerBySpringCGLIB$$63ecbbdb.getUserDetails(<generated>)
	at fr.***.digital.security.jwt.TokenProvider.getAuthentication***Connect(TokenProvider.java:112)
	at fr.***.digital.security.jwt.JWTFilter.doFilter(JWTFilter.java:47)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
	at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:121)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
	at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66)

This is my method :

    @Cacheable(value = "getUserInfo", key = "#key")
    public ***UserDetails getUserDetails(OAuth2AccessToken token, String key) {

And my spring boot config

spring:
    cache:
        mongo:
            caches:
                -
                  # TTL (in seconds).
                  ttl: 600
                  # MongoDB collection name.
                  collectionName: userInfoCache
                  # Cache name for the @Cacheable annotation.
                  cacheName: getUserInfo
                  # Value that indicates if the collection must be flushed when the application starts.
                  flushOnBoot: true

@aymhce
Copy link

aymhce commented May 18, 2017

For information, I have this problem when I use Spring Boot DevTools on my eclipse or when I do ./gradlew bootRun. There is no problem when my application is running on production environment.

@dnlprplt
Copy link
Contributor

Thanks for your input.

Considering my current workload, I won't be able to look into it immediately. But we welcome PRs.

@sake92
Copy link

sake92 commented Sep 14, 2017

Hi @danielprplt! I have some questions regarding serialization:

  1. Why does the CacheDocument have id as a String? Spring docs say that DefaultKeyGenerator generates a hashCode of all paremeters (returns Object). So, it should be an Object instance (Mongo has no problem to deal with that)?

  2. Same class, different field: String element. Serialized here to base64 here. Why was this necessary? Forcing us to implement Serializable?

That's all, I'll send a PR if you agree this should be fixed. 😄

@dnlprplt
Copy link
Contributor

Hello @sake92,

  1. Mongo can store objects fine, but we need to consider how to effectively retrieve the cached value based on the key. If the key is a random object, how can we query mongo effectively? Therefore, we chose to use a String, on which we can create an index in mongo. Also, using hashcode as a key, you can end up with collisions.

  2. We chose to use the standard serialization mechanism of Java simply because its the standard. There was a plan to support "Mongo serialization" as well. There is now a PR to allow customization of the serialization mechanisms: support for custom serializer #2

@weaamhafez
Copy link

Hi @aymhce

did you find a solution on this issue while using eclipse please?

@aymhce
Copy link

aymhce commented Mar 5, 2018

Sorry, i'm no longer work on the project that needed to use spring-cache-mongodb. However, thank you for issue fixing :)

@itoche
Copy link
Contributor

itoche commented Mar 6, 2018

@danielprplt @cyrilschumacher do you plan to merge the mentioned pull request ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants