Description
Describe the feature request
According to the spring-kafka docs (https://docs.spring.io/spring-kafka/reference/kafka/receiving-messages/listener-annotation.html) it is possible to reference the current bean of a method annotated @KafkaListener
using __listener
, but this pseudo bean is not resolved by springwolf.
Example:
@Component
public class Listener {
private final String topic = "topicname";
private final String group = "groupname";
@KafkaListener(topics = "#{__listener.topic}", groupId = "#{__listener.group}")
public void listen(Object message) {
}
public String getTopic() {
return this.topic;
}
public String getGroup() {
return this.group;
}
}
The kafka listener itself is created successfully in this case, but there is a SpelEvaluationException
thrown in springwolf code:
2024-07-27T21:37:00.479+03:00 ERROR 9656 --- [test] [ main] i.g.s.c.a.o.DefaultOperationsService : An error was encountered during operation scanning with io.github.springwolf.core.asyncapi.scanners.operations.SpringAnnotationOperationsScanner@6bee793f: Expression parsing failed
org.springframework.beans.factory.BeanExpressionException: Expression parsing failed
at org.springframework.context.expression.StandardBeanExpressionResolver.evaluate(StandardBeanExpressionResolver.java:186) ~[spring-context-6.1.11.jar:6.1.11]
at org.springframework.beans.factory.config.EmbeddedValueResolver.resolveStringValue(EmbeddedValueResolver.java:56) ~[spring-beans-6.1.11.jar:6.1.11]
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197) ~[na:na]
at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:1024) ~[na:na]
at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[na:na]
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:na]
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682) ~[na:na]
at io.github.springwolf.plugins.kafka.asyncapi.scanners.common.KafkaListenerUtil.getChannelName(KafkaListenerUtil.java:34) ~[springwolf-kafka-1.4.0.jar:na]
at io.github.springwolf.plugins.kafka.asyncapi.scanners.bindings.KafkaBindingFactory.getChannelName(KafkaBindingFactory.java:23) ~[springwolf-kafka-1.4.0.jar:na]
at io.github.springwolf.plugins.kafka.asyncapi.scanners.bindings.KafkaBindingFactory.getChannelName(KafkaBindingFactory.java:17) ~[springwolf-kafka-1.4.0.jar:na]
at io.github.springwolf.core.asyncapi.scanners.operations.annotations.SpringAnnotationMethodLevelOperationsScanner.mapMethodToOperation(SpringAnnotationMethodLevelOperationsScanner.java:73) ~[springwolf-core-1.4.0.jar:na]
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197) ~[na:na]
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179) ~[na:na]
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179) ~[na:na]
at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:1024) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[na:na]
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151) ~[na:na]
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:na]
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596) ~[na:na]
at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:276) ~[na:na]
at java.base/java.util.HashMap$KeySpliterator.forEachRemaining(HashMap.java:1715) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:575) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:260) ~[na:na]
at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:616) ~[na:na]
at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:622) ~[na:na]
at java.base/java.util.stream.ReferencePipeline.toList(ReferencePipeline.java:627) ~[na:na]
at io.github.springwolf.core.asyncapi.scanners.operations.SpringAnnotationOperationsScanner.mapToOperations(SpringAnnotationOperationsScanner.java:31) ~[springwolf-core-1.4.0.jar:na]
at io.github.springwolf.core.asyncapi.scanners.operations.SpringAnnotationOperationsScanner.scan(SpringAnnotationOperationsScanner.java:25) ~[springwolf-core-1.4.0.jar:na]
at io.github.springwolf.core.asyncapi.operations.DefaultOperationsService.findOperations(DefaultOperationsService.java:34) ~[springwolf-core-1.4.0.jar:na]
at io.github.springwolf.core.asyncapi.DefaultAsyncApiService.initAsyncAPI(DefaultAsyncApiService.java:71) ~[springwolf-core-1.4.0.jar:na]
at io.github.springwolf.core.asyncapi.DefaultAsyncApiService.getAsyncAPI(DefaultAsyncApiService.java:42) ~[springwolf-core-1.4.0.jar:na]
at io.github.springwolf.core.SpringwolfInitApplicationListener.onApplicationEvent(SpringwolfInitApplicationListener.java:31) ~[springwolf-core-1.4.0.jar:na]
at io.github.springwolf.core.SpringwolfInitApplicationListener.onApplicationEvent(SpringwolfInitApplicationListener.java:17) ~[springwolf-core-1.4.0.jar:na]
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:185) ~[spring-context-6.1.11.jar:6.1.11]
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:178) ~[spring-context-6.1.11.jar:6.1.11]
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:156) ~[spring-context-6.1.11.jar:6.1.11]
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:452) ~[spring-context-6.1.11.jar:6.1.11]
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:385) ~[spring-context-6.1.11.jar:6.1.11]
at org.springframework.boot.context.event.EventPublishingRunListener.ready(EventPublishingRunListener.java:109) ~[spring-boot-3.3.2.jar:3.3.2]
at org.springframework.boot.SpringApplicationRunListeners.lambda$ready$6(SpringApplicationRunListeners.java:80) ~[spring-boot-3.3.2.jar:3.3.2]
at java.base/java.lang.Iterable.forEach(Iterable.java:75) ~[na:na]
at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:118) ~[spring-boot-3.3.2.jar:3.3.2]
at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:112) ~[spring-boot-3.3.2.jar:3.3.2]
at org.springframework.boot.SpringApplicationRunListeners.ready(SpringApplicationRunListeners.java:80) ~[spring-boot-3.3.2.jar:3.3.2]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:349) ~[spring-boot-3.3.2.jar:3.3.2]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1363) ~[spring-boot-3.3.2.jar:3.3.2]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1352) ~[spring-boot-3.3.2.jar:3.3.2]
at com.example.test.TestApplication.main(TestApplication.java:10) ~[main/:na]
Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field '__listener' cannot be found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext' - maybe not public or not valid?
at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:229) ~[spring-expression-6.1.11.jar:6.1.11]
at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:112) ~[spring-expression-6.1.11.jar:6.1.11]
at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:100) ~[spring-expression-6.1.11.jar:6.1.11]
at org.springframework.expression.spel.ast.CompoundExpression.getValueRef(CompoundExpression.java:60) ~[spring-expression-6.1.11.jar:6.1.11]
at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:96) ~[spring-expression-6.1.11.jar:6.1.11]
at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:114) ~[spring-expression-6.1.11.jar:6.1.11]
at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:273) ~[spring-expression-6.1.11.jar:6.1.11]
at org.springframework.context.expression.StandardBeanExpressionResolver.evaluate(StandardBeanExpressionResolver.java:183) ~[spring-context-6.1.11.jar:6.1.11]
... 54 common frames omitted
Motivation
This feature should be implemented to make springwolf more compatible with org.springframework.kafka.annotation.KafkaListener
annotation.
Technical details
I haven't studied the source code of springwolf enough to know how to implement this.
Describe alternatives you've considered
I can always replace usages of the __listener
bean to something else.