Closed jjpianta closed 1 year ago
got the same bug.
my Cacheable:
@Cacheable(value = "myValue", key = "#myKey", cacheManager = "myManager",
unless = "#result.erreur != null && #result.erreur.myEnumValue == T(com.xxx.MyEnum).YYY")
work fine calling it without async.....
but if done with
CompletableFuture.supplyAsync(() -> my function())
Error :
2021-03-31T09:22:34.248-04:00 [APP/PROC/WEB/0] [OUT] {"@timestamp":"2021-03-31T13:22:34.247+00:00","@version":1,"message":"Une erreur technique est survenue lors de l'appel \u00E0 InformationTelephoneGateway.","logger_name":"com.xxx.MyServiceimpl","thread_name":"ForkJoinPool.commonPool-worker-1","level":"ERROR","level_value":40000,"stack_trace":"org.springframework.expression.spel.SpelEvaluationException: EL1005E: Type cannot be found 'com.xxx.MyEnum'\n\tat org.springframework.expression.spel.support.StandardTypeLocator.findType(StandardTypeLocator.java:117)\n\tat org.springframework.expression.spel.ExpressionState.findType(ExpressionState.java:155)\n\tat org.springframework.expression.spel.ast.TypeReference.getValueInternal(TypeReference.java:69)\n\tat org.springframework.expression.spel.ast.CompoundExpression.getValueRef(CompoundExpression.java:55)\n\tat org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:91)\n\tat org.springframework.expression.spel.ast.OpEQ.getValueInternal(OpEQ.java:43)\n\tat org.springframework.expression.spel.ast.OpEQ.getValueInternal(OpEQ.java:32)\n\tat org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:188)\n\tat org.springframework.expression.spel.ast.OpAnd.getBooleanValue(OpAnd.java:57)\n\tat org.springframework.expression.spel.ast.OpAnd.getValueInternal(OpAnd.java:52)\n\tat org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:117)\n\tat org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:308)\n\tat org.springframework.cache.interceptor.CacheOperationExpressionEvaluator.unless(CacheOperationExpressionEvaluator.java:113)\n\tat org.springframework.cache.interceptor.CacheAspectSupport$CacheOperationContext.canPutToCache(CacheAspectSupport.java:783)\n\tat org.springframework.cache.interceptor.CacheAspectSupport$CachePutRequest.apply(CacheAspectSupport.java:835)\n\tat org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:430)\n\tat org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:346)\n\tat org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:61)\n\tat org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\n\tat org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\n\tat org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)\n\tat org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)\n\tat org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)\n\tat org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)\n\tat
stupid workarround:
@Cacheable(value = "infoTelephones", key = "#numeroTelephone", cacheManager = "infoTelephonesCacheManager",
unless = "#result.notCacheable")
and move the test in the method added on the object...
It turned out it was an issue with StandardTypeLocator used by Thymeleaf Context: dunno why, but sometimes it gets created with System classloader, so it can't resolve our app types. We made a dirty fix supplying a TypeLocator initialized with our web app's classloader
Context ctx = new Context(locale);
StandardEvaluationContext delegate = new StandardEvaluationContext();
StandardTypeLocator tl = new StandardTypeLocator(MyClass.class.getClassLoader());
delegate.setTypeLocator(tl);
EvaluationContext evaluationContext = new ThymeleafEvaluationContextWrapper(delegate);
ctx.setVariable(ThymeleafEvaluationContext.THYMELEAF_EVALUATION_CONTEXT_CONTEXT_VARIABLE_NAME,
evaluationContext);
Hey @jjpianta, have we got any updates regarding this? Can this be solved without some dirty work around?
Hi @vvvinamer. No, here we have no update, we're still going with the dirty fix.
Cheers J.J.
On Mon, 16 May 2022 at 20:54, vvvinamer @.***> wrote:
Hey @jjpianta https://github.com/jjpianta, have we got any updates regarding this? Can this be solved without some dirty work around?
— Reply to this email directly, view it on GitHub https://github.com/spring-projects/spring-framework/issues/26253#issuecomment-1128021916, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABVFRMXUWW4GYN5XVHYEMXLVKKKWVANCNFSM4UUY53YQ . You are receiving this because you were mentioned.Message ID: @.***>
I still run into this as of 2023 with java 18 + spring boot 2.7.7 (spring framework 5.3.24)
We made a dirty fix supplying a TypeLocator initialized with our web app's classloader
I don't necessarily consider that a "dirty fix" but rather a robust solution.
The SpEL expression parser needs to be able to reliably locate user types, and providing a suitable ClassLoader
serves that purpose.
This issue has been repurposed to improve the documentation regarding proper configuration of the StandardTypeLocator
.
See https://github.com/spring-projects/spring-framework/commit/10de295a7216fe51566bb977714953ffcdd17574 for details.
Hi, we are experiencing such a strange behavior using
SPEL T()
operator to get references to custom enums or types in our thymeleaf templates: everything goes straight till we get random failures in resolving our custom types. "random" means that same expression sometimes get parsed properly and sometimes don't. It looks like failures occur only in asynch context (StreamingResponseBody
's callbacks and@Asynch
annotated methods)Same issue submitted to the Thymeleaf team
see full stack trace