Spring App Error: EL1008E

14,275

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'.

Share:
14,275

Related videos on Youtube

DaniloV
Author by

DaniloV

Software Consultant based in Hampshire, England. Currently on-site learning Spring Integration and Java 8. Interested in video games!

Updated on June 04, 2022

Comments

  • DaniloV
    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 an ArrayList. 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
      Hrabosch about 8 years
      Can you add a cache config xml?
  • DaniloV
    DaniloV about 8 years
    Thank 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 the unless expression in so I didn't think to look there.
  • DaniloV
    DaniloV about 8 years
    Hmm, 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
    Gary Russell about 8 years
    Doh - sorry yes; I was thrown by the original question.