Spring App Error: EL1008E
The error seems pretty clear to me.
It's not clear what you are trying to do. The #result
variable is a reference to the ...er... result of calling the method
- i.e. the ArrayList
.
ArrayList
does not have a isValid()
or getValid()
method.
The documentation about Conditional Caching describes what variables are available to you.
As you can see I have tried setting a public getter method
I don't see any such thing.
You can do things like result.size() > 0
, a != 'foo'
.
Related videos on Youtube
DaniloV
Software Consultant based in Hampshire, England. Currently on-site learning Spring Integration and Java 8. Interested in video games!
Updated on June 04, 2022Comments
-
DaniloV almost 2 years
I have been working on a Spring Integration project using Enterprise Integration Patterns to consume MQ messages, do some processing, then write them to another queue.
My problem appears very similar to this one however the accepted answer hasn't fixed it for me.
After receiving a response from an external web service, my
@Cacheable
@Component
class returns the body as anArrayList
. I am getting the following error:org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 1): Property or field 'valid' cannot be found on object of type 'java.util.ArrayList' - maybe not public?
Here is, what I believe to be, the offending class:
import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.apache.curator.x.discovery.ServiceCache; import org.apache.curator.x.discovery.ServiceInstance; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestTemplate; @Component public class DirectoryRepo { @Autowired private CacheManager cacheManager; @Autowired private ServiceCache<ServiceDetail> directoryServiceCache; @Autowired private RestTemplate restTemplate; private ArrayList<X> response; private static final Logger logger = LogManager.getLogger(); @Cacheable(value = "X", unless = "!#result.valid") public ArrayList<X> checkForX(String a, String b, String c, String d) { try { //code omitted HttpHeaders headers = new HttpHeaders(); headers.add("token", service.getPayload().getToken()); ResponseEntity<X[]> responseEntity = restTemplate .exchange(request, HttpMethod.GET, new HttpEntity<>( headers), X[].class); if (responseEntity != null && responseEntity.hasBody()) { response = new ArrayList<X>(Arrays.asList(responseEntity.getBody())); return response; } else { logger.debug("received unexpected responseEntity: {}", responseEntity); } } catch (RestClientException e) { logger.error("failed to get X - {}", e.getMessage(), e); } throw new ServiceException( "failed to get X - Directory service unavailable"); } public ArrayList<X> getResponse() { return this.response; } /** * Clears out all entries from the X cache. */ @CacheEvict(value = "X", allEntries = true) public void clearXCache() { logger.trace("cacheManager:{}", cacheManager); } }
As you can see I have tried setting a public getter method, but the exception still occurs:
org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 1): Property or field 'valid' cannot be found on object of type 'java.util.ArrayList' - maybe not public ? at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:224) ~[spring-expression-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:94) ~[spring-expression-4.2.4.RELEASE.jar:4.2.4.RELEASE ] at org.springframework.expression.spel.ast.PropertyOrFieldReference.access$000(PropertyOrFieldReference.java:46) ~[spring-expression-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.expression.spel.ast.PropertyOrFieldReference$AccessorLValue.getValue(PropertyOrFieldReference.java:374) ~[spring-expression-4.2.4.RELEASE.jar:4.2.4 .RELEASE] at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:88) ~[spring-expression-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:170) ~[spring-expression-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.expression.spel.ast.OperatorNot.getValueInternal(OperatorNot.java:47) ~[spring-expression-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.expression.spel.ast.OperatorNot.getValueInternal(OperatorNot.java:36) ~[spring-expression-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:131) ~[spring-expression-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:299) ~[spring-expression-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.cache.interceptor.ExpressionEvaluator.unless(ExpressionEvaluator.java:123) ~[spring-context-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.cache.interceptor.CacheAspectSupport$CacheOperationContext.canPutToCache(CacheAspectSupport.java:623) ~[spring-context-4.2.4.RELEASE.jar:4.2.4.RELE ASE] at org.springframework.cache.interceptor.CacheAspectSupport$CachePutRequest.apply(CacheAspectSupport.java:675) ~[spring-context-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:361) ~[spring-context-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:302) ~[spring-context-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:61) ~[spring-context-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655) ~[spring-aop-4.2.4.RELEASE.jar:4.2.4.RELEASE] at somepackage.DirectoryRepo$$EnhancerBySpringCGLIB$$f7709589.checkForX(<generated>) ~[DirectoryRepo.class:?] at somepackage.DirectoryService.getX(DirectoryService.java:66) ~[DirectoryService.class:?]
context.xml:
<?xml version='1.0' encoding='utf-8'?> <Context displayName="appName" path="/appName" copyXML="true"> </Context>
-
Hrabosch about 8 yearsCan you add a cache config xml?
-
-
DaniloV about 8 yearsThank you very much, Gary. Apologies if my question wasn't clear (first timer, here)! This has resolved the issue after changing it to
#result.isEmpty()
instead. Someone else added theunless
expression in so I didn't think to look there. -
DaniloV about 8 yearsHmm, no. "Cache the result, except if it is empty" is how I was reading it. If there are no results then the condition is
true
meaning the cache is vetoed. Similar to the example in your link:unless="#result.hardback
"Cache the result, except if it's hardback." -
Gary Russell about 8 yearsDoh - sorry yes; I was thrown by the original question.