3

Getting below issue post upgrading Spring boot app to Java 11, this was working fine even on 2.1 spring boot on Jdk 8

Jdk : Correto 11

Spring boot : 2.2.13.RELEASE

Spring Integration : 5.2.11.RELEASE

Code :

 .route("headers.get(T(com.foo.integration.FlowHeaders).FEED).getProcessingMode()",
                  m -> m.subFlowMapping(Feed.ProcessingMode.stream, this.streamFlow(sinkStreamProcessingHandler))
                        .subFlowMapping(Feed.ProcessingMode.batch,
                              this.batchFlow(sinkBatchProcessingHandler, props))
                        .subFlowMapping(Feed.ProcessingMode.group,

Exception :

   ExceptionFlow - Exception in flow ... [EL1005E: Type cannot be found 'com.foo.integration.FlowHeaders'] 
    org.springframework.messaging.MessageHandlingException: Expression evaluation failed: headers.get(T(com.foo.integration.FlowHeaders).FEED).getProcessingMode(); 
nested exception is org.springframework.expression.spel.SpelEvaluationException: EL1005E: Type cannot be found 'com.foo.integration.FlowHeaders'
        at org.springframework.integration.support.utils.IntegrationUtils.wrapInHandlingExceptionIfNecessary(IntegrationUtils.java:191)
        at org.springframework.integration.util.AbstractExpressionEvaluator.evaluateExpression(AbstractExpressionEvaluator.java:137)
        at org.springframework.integration.handler.ExpressionEvaluatingMessageProcessor.processMessage(ExpressionEvaluatingMessageProcessor.java:107)
        at org.springframework.integration.router.AbstractMessageProcessingRouter.getChannelKeys(AbstractMessageProcessingRouter.java:84)
        at org.springframework.integration.router.AbstractMappingMessageRouter.determineTargetChannels(AbstractMappingMessageRouter.java:202)
        at org.springframework.integration.router.AbstractMessageRouter.handleMessageInternal(AbstractMessageRouter.java:170)
        at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:177)
        at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:115)

Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1005E: Type cannot be found 'com.wellmanage.wfg.fdps.integration.FDPSHeaders'
    at org.springframework.expression.spel.support.StandardTypeLocator.findType(StandardTypeLocator.java:117)
    at org.springframework.expression.spel.ExpressionState.findType(ExpressionState.java:155)
    at org.springframework.expression.spel.ast.TypeReference.getValueInternal(TypeReference.java:69)
    at org.springframework.expression.spel.ast.CompoundExpression.getValueRef(CompoundExpression.java:55)
    at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:91)
    at org.springframework.expression.spel.ast.MethodReference.getArguments(MethodReference.java:164)
    at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:94)
    at org.springframework.expression.spel.ast.CompoundExpression.getValueRef(CompoundExpression.java:61)
    at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:91)
    at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:117)
    at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:375)
    at org.springframework.integration.util.AbstractExpressionEvaluator.evaluateExpression(AbstractExpressionEvaluator.java:171)
    at org.springframework.integration.util.AbstractExpressionEvaluator.evaluateExpression(AbstractExpressionEvaluator.java:129)

UPDATE

This change somehow made it work though not completely sure as this is the same code as in the oob bean

@Primary       @Bean(IntegrationContextUtils.INTEGRATION_EVALUATION_CONTEXT_BEAN_NAME)
           public IntegrationEvaluationContextFactoryBean  evaluationContextFactoryBean(){
              var factoryBean = new IntegrationEvaluationContextFactoryBean();
              factoryBean.setTypeLocator(new CustomStandardTypeLocator());
              return factoryBean;
           }
        
           static class CustomStandardTypeLocator extends StandardTypeLocator {
        
              @Override
              public Class<?> findType(String typeName) throws EvaluationException {
                 LOG.info("Finding type {} in classloader {}", typeName, ClassUtils.getDefaultClassLoader().getName());
                 return super.findType(typeName);
              }
           }
Gaurav Rawat
  • 1,294
  • 1
  • 25
  • 52
  • 1
    The error doesn't match the expression `T(com.foo.integration.FlowHeaders)` (no `integration.`). – Gary Russell Dec 02 '21 at 18:49
  • That was a typo @GaryRussell let me correct that had added to obfuscate the org name – Gaurav Rawat Dec 02 '21 at 19:13
  • 1
    If the class is truly present then, perhaps, you are somehow using a `SimpleEvaluationContext` instead of a `StandardEvaluationContext` (it doesn't allow the `T` operator), but I don't see how that's possible if you are using standard components. – Gary Russell Dec 02 '21 at 19:38
  • yes not sure that is possible as AbstractExpressionEvaluator internally uses StandardEvaluationContext I guess .. also this is a standard Spring integration Integration flow . Also this seems to be coming up when we upgrade to Java 11 across 2.1 spring boot as well so not sure related to the upgrade/classloader issue ? – Gaurav Rawat Dec 02 '21 at 19:46
  • Right; that's what I mean by "I don't see how that's possible". Have you tried with, say, OpenJDK 11? – Gary Russell Dec 02 '21 at 19:49
  • 1
    yes @GaryRussell added more details (for caused by) we will try to debug seems StandardTypeLocator classloader somehow didn't load the class which is in a dependent gradle module somehow . We as an org are on aws and have choose corretto as the standard there so didnt try on openJDK . Also did doesnt happen when we run locally but on the server via jar so also checking if any issue with gradle bundling the deps on jdk11 as a possibility – Gaurav Rawat Dec 02 '21 at 20:43
  • 1
    If it helps you debug it, you can add a custom `TypeLocator` in the `IntegrationEvaluationContextFactoryBean` bean (its bean name is `IntegrationContextUtils.INTEGRATION_EVALUATION_CONTEXT_BEAN_NAME`). – Gary Russell Dec 02 '21 at 21:37
  • Thanks @GaryRussell using a custom `IntegrationEvaluationContextFactoryBean` fixed the error but still need to figure out why though . maybe a classloading issue ... – Gaurav Rawat Dec 03 '21 at 13:18
  • Can you show, please, what you did? Perhaps the same has to be done in the out-of-the-box bean? – Artem Bilan Dec 08 '21 at 14:30
  • HI @ArtemBilan just created a custom bean that's it with some logging . Initially I observed the OOB one gets called and then this .. Not sure the classloader getting picked up was the issue though I didnt change any code specifically . Added the snipped in the question above – Gaurav Rawat Dec 08 '21 at 16:34
  • 1
    Hm. It indeed does the same what is there by default in the `StandardEvaluationContext`: `this.typeLocator = new StandardTypeLocator();`. And we don't propagate there any classloaders... Would be great to be able to reproduce and perhaps in the end we really must propagate over there a `getBeanFactory().getBeanClassLoader()`. since it feels like that your `CustomStandardTypeLocator` is really loaded already via your `@Configuration`'s classloader... – Artem Bilan Dec 08 '21 at 17:08

0 Answers0