注意:我使用的是 Spring Boot 2.2.0.RELEASE,所以它与 this 无关。
我有一个
MessagingGateway
,如下:
@Gateway(
requestChannel = "myChannel",
headers = @GatewayHeader(
name = "tenantId",
expression = "T(com.company.package.ContextHolder).getContext()?.tenant?.identifier"))
void publishEvent(@Header(value = "eventType") String eventType,
@Payload Object payload);
我的
ContextHolder
类类似于SecurityContextHolder
或RequestContextHolder
,我在其中添加了一些基本请求相关信息,就像SecurityContext
一样。
问题是,这在我的机器上运行得很好,并且对于大多数对
publishEvent
方法的调用,它也在服务器上运行。然而,对于某些方法,我得到:
org.springframework.expression.spel.SpelEvaluationException: EL1005E: Type cannot be found 'com.company.package.ContextHolder'
at org.springframework.expression.spel.support.StandardTypeLocator.findType(StandardTypeLocator.java:117) ~[spring-expression-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.expression.spel.ExpressionState.findType(ExpressionState.java:155) ~[spring-expression-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.expression.spel.ast.TypeReference.getValueInternal(TypeReference.java:69) ~[spring-expression-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.expression.spel.ast.CompoundExpression.getValueRef(CompoundExpression.java:55) ~[spring-expression-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:91) ~[spring-expression-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:112) ~[spring-expression-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:330) ~[spring-expression-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.integration.gateway.GatewayMethodInboundMessageMapper.evaluateHeaders(GatewayMethodInboundMessageMapper.java:213) ~[spring-integration-core-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.integration.gateway.GatewayMethodInboundMessageMapper.access$1000(GatewayMethodInboundMessageMapper.java:86) ~[spring-integration-core-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.integration.gateway.GatewayMethodInboundMessageMapper$DefaultMethodArgsMessageMapper.buildMessage(GatewayMethodInboundMessageMapper.java:434) ~[spring-integration-core-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.integration.gateway.GatewayMethodInboundMessageMapper$DefaultMethodArgsMessageMapper.toMessage(GatewayMethodInboundMessageMapper.java:340) ~[spring-integration-core-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.integration.gateway.GatewayMethodInboundMessageMapper$DefaultMethodArgsMessageMapper.toMessage(GatewayMethodInboundMessageMapper.java:288) ~[spring-integration-core-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.integration.gateway.GatewayMethodInboundMessageMapper.mapArgumentsToMessage(GatewayMethodInboundMessageMapper.java:198) ~[spring-integration-core-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.integration.gateway.GatewayMethodInboundMessageMapper.toMessage(GatewayMethodInboundMessageMapper.java:192) ~[spring-integration-core-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.integration.gateway.GatewayMethodInboundMessageMapper.toMessage(GatewayMethodInboundMessageMapper.java:86) ~[spring-integration-core-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.integration.support.converter.SimpleMessageConverter.toMessage(SimpleMessageConverter.java:111) ~[spring-integration-core-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.messaging.core.AbstractMessageSendingTemplate.doConvert(AbstractMessageSendingTemplate.java:182) ~[spring-messaging-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.messaging.core.AbstractMessageSendingTemplate.convertAndSend(AbstractMessageSendingTemplate.java:150) ~[spring-messaging-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.messaging.core.AbstractMessageSendingTemplate.convertAndSend(AbstractMessageSendingTemplate.java:143) ~[spring-messaging-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.integration.gateway.MessagingGatewaySupport.send(MessagingGatewaySupport.java:417) ~[spring-integration-core-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.integration.gateway.GatewayProxyFactoryBean.sendOrSendAndReceive(GatewayProxyFactoryBean.java:576) ~[spring-integration-core-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.integration.gateway.GatewayProxyFactoryBean.invokeGatewayMethod(GatewayProxyFactoryBean.java:508) ~[spring-integration-core-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.integration.gateway.GatewayProxyFactoryBean.doInvoke(GatewayProxyFactoryBean.java:478) ~[spring-integration-core-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.integration.gateway.GatewayProxyFactoryBean.invoke(GatewayProxyFactoryBean.java:468) ~[spring-integration-core-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.2.0.RELEASE.jar!/:5.2.0.RELEASE]
at com.sun.proxy.$Proxy168.publishEvent(Unknown Source) ~[na:na]
at com.company.project.services.SomeService.lambda$bulk$2(SomeService.java:434) ~[project-api-0.5.0.RELEASE.jar!/:na]
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183) ~[na:na]
at java.base/java.util.stream.SpinedBuffer.forEach(SpinedBuffer.java:246) ~[na:na]
at java.base/java.util.stream.Nodes$SpinedNodeBuilder.forEach(Nodes.java:1270) ~[na:na]
at java.base/java.util.stream.Nodes$InternalNodeSpliterator$OfRef.forEachRemaining(Nodes.java:1105) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484) ~[na:na]
at java.base/java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:290) ~[na:na]
at java.base/java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:746) ~[na:na]
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290) ~[na:na]
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020) ~[na:na]
at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656) ~[na:na]
at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594) ~[na:na]
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183) ~[na:na]
并且
bulk
的 SomeService
方法有点像:
StreamSupport
.stream(worksheet.spliterator(), true)
.skip(1)
.forEach(row -> {
// insert row into db and publish message
this.applicationEventGateway.publishEvent("rowCreated", row);
});
Worksheet
是 Apache POI 工作表。我知道该方法是在并行流中调用的,但是会导致找不到类的错误吗?我错过了什么?
感觉就像
parallel
对于Stream
使它寻找不同的ClassLoader
。
如果您能在没有
parallel
的情况下确认它是如何工作的,那就太好了。
感觉 Spring Integration 的
IntegrationEvaluationContextFactoryBean
可以用 StandardTypeLocator
中的 ClassLoader
修复为 BeanFactory
。
您可以考虑一种解决方法,例如使用
IntegrationEvaluationContextFactoryBean
名称为 IntegrationContextUtils.INTEGRATION_EVALUATION_CONTEXT_BEAN_NAME
创建一个 bean,并根据 typeLocator
类加载器将 StandardTypeLocator
设置为 BeanFactory
。
如果是这种情况,请提出 GH 问题,以便我们尽快修复。