springwolf / springwolf-core

Automated documentation for event-driven applications built with Spring Boot
https://www.springwolf.dev
Apache License 2.0
250 stars 72 forks source link

StackOverflow error on AsyncAPI creation #1052

Open slava110 opened 1 day ago

slava110 commented 1 day ago

Describe the bug StackOverflow error on AsyncAPI creation java.lang.RuntimeException: Error occured during creation of AsyncAPI Caused by: java.lang.StackOverflowError: null In io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties

Dependencies and versions used SpringBoot 3.3.5 Java 17

implementation("io.github.springwolf:springwolf-amqp:1.8.0")
implementation("io.github.springwolf:springwolf-amqp-binding:1.8.0")
implementation("io.github.springwolf:springwolf-ui:1.8.0")

Code example

RabbitMQ Configuration ```kotlin @Configuration class RabbitConfig { @Bean("paymentRequestQueue") fun requestQueue(): Queue = Queue(AMQPConstants.QUEUE_PAYMENT_REQUESTS) @Bean("paymentResponseQueue") fun responseQueue(): Queue = Queue(AMQPConstants.QUEUE_PAYMENT_RESPONSES) @Bean("rabbitListenerContainerFactory") fun listenerContainerFactory( conFactory: ConnectionFactory ) = SimpleRabbitListenerContainerFactory().apply { setConnectionFactory(conFactory) setMessageConverter(ProtobufMessageConverterAMQP( PaymentRequest.getDefaultInstance() )) setAcknowledgeMode(AcknowledgeMode.MANUAL) } @Bean fun rabbitTemplate(conFactory: ConnectionFactory): RabbitTemplate { val rabbitTemplate = RabbitTemplate(conFactory) rabbitTemplate.messageConverter = ProtobufMessageConverterAMQP( PaymentResponse.getDefaultInstance() ) return rabbitTemplate } } ```
Consumer ```kotlin @Component class PaymentRequestConsumer { @Autowired lateinit var responseProducer: PaymentResponseProducer @RabbitListener(queues = [AMQPConstants.QUEUE_PAYMENT_REQUESTS]) suspend fun process( @Header(AmqpHeaders.CHANNEL) channel: Channel, @Header(AmqpHeaders.DELIVERY_TAG) deliveryTag: Long, @Payload requestMsg: PaymentRequest ) { println("Processed request! ${requestMsg.id}") responseProducer.paymentRespond(paymentResponse { id = 1 status = PaymentResponse.Status.SUCCESSFUL }) channel.basicAck(deliveryTag, false) } } ```
Producer ```kotlin @Component class PaymentResponseProducer { @Autowired private lateinit var template: RabbitTemplate @AsyncPublisher( operation = AsyncOperation( channelName = AMQPConstants.QUEUE_PAYMENT_RESPONSES ) ) @AmqpAsyncOperationBinding fun paymentRespond(response: PaymentResponse) { template.convertAndSend(AMQPConstants.QUEUE_PAYMENT_RESPONSES, response) } } ```
Spring `application.properties` ```kotlin spring.application.name=Delivery Microservice spring.rabbitmq.host=localhost spring.rabbitmq.port=5672 spring.rabbitmq.username=guest spring.rabbitmq.password=guest ######### # Springwolf configuration # Copied from example project springwolf.enabled=true springwolf.docket.base-package=com.microdelivery.payment.consumers springwolf.docket.info.title=${spring.application.name} springwolf.docket.info.version=1.0.0 springwolf.docket.info.description=Springwolf example project to demonstrate springwolfs abilities springwolf.docket.info.terms-of-service=http://asyncapi.org/terms springwolf.docket.info.extension-fields.x-api-audience=company-internal springwolf.docket.info.extension-fields.x-generator=springwolf springwolf.docket.info.contact.name=springwolf springwolf.docket.info.contact.email=example@example.com springwolf.docket.info.contact.url=https://github.com/springwolf/springwolf-core springwolf.docket.info.contact.extension-fields.x-phone=+49 123 456789 springwolf.docket.info.license.name=Apache License 2.0 springwolf.docket.info.license.extension-fields.x-desc=some description springwolf.docket.servers.amqp-server.protocol=amqp springwolf.docket.servers.amqp-server.host=${spring.rabbitmq.host}:${spring.rabbitmq.port} springwolf.plugin.amqp.publishing.enabled=true ```

Stack trace and error logs

Error ``` java.lang.RuntimeException: Error occured during creation of AsyncAPI at io.github.springwolf.core.asyncapi.DefaultAsyncApiService.getAsyncAPI(DefaultAsyncApiService.java:48) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.SpringwolfInitApplicationListener.onApplicationEvent(SpringwolfInitApplicationListener.java:31) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.SpringwolfInitApplicationListener.onApplicationEvent(SpringwolfInitApplicationListener.java:17) ~[springwolf-core-1.8.0.jar:na] at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:185) ~[spring-context-6.1.14.jar:6.1.14] at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:178) ~[spring-context-6.1.14.jar:6.1.14] at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:156) ~[spring-context-6.1.14.jar:6.1.14] at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:452) ~[spring-context-6.1.14.jar:6.1.14] at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:385) ~[spring-context-6.1.14.jar:6.1.14] at org.springframework.boot.context.event.EventPublishingRunListener.ready(EventPublishingRunListener.java:109) ~[spring-boot-3.3.5.jar:3.3.5] at org.springframework.boot.SpringApplicationRunListeners.lambda$ready$6(SpringApplicationRunListeners.java:80) ~[spring-boot-3.3.5.jar:3.3.5] 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.5.jar:3.3.5] at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:112) ~[spring-boot-3.3.5.jar:3.3.5] at org.springframework.boot.SpringApplicationRunListeners.ready(SpringApplicationRunListeners.java:80) ~[spring-boot-3.3.5.jar:3.3.5] at org.springframework.boot.SpringApplication.run(SpringApplication.java:349) ~[spring-boot-3.3.5.jar:3.3.5] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1363) ~[spring-boot-3.3.5.jar:3.3.5] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1352) ~[spring-boot-3.3.5.jar:3.3.5] at com.microdelivery.payment.PaymentApplicationKt.main(PaymentApplication.kt:13) ~[main/:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na] at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:50) ~[spring-boot-devtools-3.3.5.jar:3.3.5] Caused by: java.lang.StackOverflowError: null at java.base/java.util.LinkedHashMap.getOrDefault(LinkedHashMap.java:453) ~[na:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:39) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:33) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.lambda$removeAvroProperties$0(AvroSchemaPostProcessor.java:49) ~[springwolf-core-1.8.0.jar:na] at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721) ~[na:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:49) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:33) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.lambda$removeAvroProperties$0(AvroSchemaPostProcessor.java:49) ~[springwolf-core-1.8.0.jar:na] at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721) ~[na:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:49) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:33) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.lambda$removeAvroProperties$0(AvroSchemaPostProcessor.java:49) ~[springwolf-core-1.8.0.jar:na] at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721) ~[na:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:49) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:33) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.lambda$removeAvroProperties$0(AvroSchemaPostProcessor.java:49) ~[springwolf-core-1.8.0.jar:na] Caused by: java.lang.StackOverflowError: null at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721) ~[na:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:49) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:33) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.lambda$removeAvroProperties$0(AvroSchemaPostProcessor.java:49) ~[springwolf-core-1.8.0.jar:na] at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721) ~[na:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:49) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:33) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.lambda$removeAvroProperties$0(AvroSchemaPostProcessor.java:49) ~[springwolf-core-1.8.0.jar:na] at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721) ~[na:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:49) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:33) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.lambda$removeAvroProperties$0(AvroSchemaPostProcessor.java:49) ~[springwolf-core-1.8.0.jar:na] at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721) ~[na:na] ```
github-actions[bot] commented 1 day ago

Welcome to Springwolf. Thanks a lot for reporting your first issue. Please check out our contributors guide and feel free to join us on discord.

timonback commented 1 day ago

Hi @slava110 Thank you for the detailed report.

Enabling the debug logs will potentially add a bit more context: https://www.springwolf.dev/docs/faq#show-debug-output-in-the-logs

Can you share the payload PaymentResponse class? I suspect some recursive structure, which regardless should be handled by Springwolf.

slava110 commented 1 day ago

Hi. Thank you for quick response. Here is my log after changing SpringWolf's logging level to DEBUG:

Log ``` 2024-11-03T14:01:40.173+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] .g.s.c.SpringwolfInitApplicationListener : Triggering asyncapi creation 2024-11-03T14:01:40.173+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.asyncapi.DefaultAsyncApiService : Building AsyncAPI document 2024-11-03T14:01:40.179+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Scanning for Component classes in com.microdelivery.payment.consumers 2024-11-03T14:01:40.232+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: com.microdelivery.payment.consumers.PaymentRequestConsumer 2024-11-03T14:01:40.235+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Scanning for Component classes in com.microdelivery.payment.consumers 2024-11-03T14:01:40.237+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: com.microdelivery.payment.consumers.PaymentRequestConsumer 2024-11-03T14:01:40.258+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.s.c.a.AnnotationScannerUtil : Scanning class "com.microdelivery.payment.consumers.PaymentRequestConsumer" for @"io.github.springwolf.core.asyncapi.annotations.AsyncListener" annotated methods 2024-11-03T14:01:40.274+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Scanning for Component classes in com.microdelivery.payment.consumers 2024-11-03T14:01:40.278+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: com.microdelivery.payment.consumers.PaymentRequestConsumer 2024-11-03T14:01:40.279+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Scanning for Component classes in com.microdelivery.payment.consumers 2024-11-03T14:01:40.285+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: com.microdelivery.payment.consumers.PaymentRequestConsumer 2024-11-03T14:01:40.287+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.s.c.a.AnnotationScannerUtil : Scanning class "com.microdelivery.payment.consumers.PaymentRequestConsumer" for @"io.github.springwolf.core.asyncapi.annotations.AsyncListener" annotation 2024-11-03T14:01:40.290+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Scanning for Component classes in com.microdelivery.payment.consumers 2024-11-03T14:01:40.293+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: com.microdelivery.payment.consumers.PaymentRequestConsumer 2024-11-03T14:01:40.294+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Scanning for Component classes in com.microdelivery.payment.consumers 2024-11-03T14:01:40.297+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: com.microdelivery.payment.consumers.PaymentRequestConsumer 2024-11-03T14:01:40.298+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.s.c.a.AnnotationScannerUtil : Scanning class "com.microdelivery.payment.consumers.PaymentRequestConsumer" for @"io.github.springwolf.core.asyncapi.annotations.AsyncPublisher" annotated methods 2024-11-03T14:01:40.299+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Scanning for Component classes in com.microdelivery.payment.consumers 2024-11-03T14:01:40.303+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: com.microdelivery.payment.consumers.PaymentRequestConsumer 2024-11-03T14:01:40.304+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Scanning for Component classes in com.microdelivery.payment.consumers 2024-11-03T14:01:40.308+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: com.microdelivery.payment.consumers.PaymentRequestConsumer 2024-11-03T14:01:40.309+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.s.c.a.AnnotationScannerUtil : Scanning class "com.microdelivery.payment.consumers.PaymentRequestConsumer" for @"io.github.springwolf.core.asyncapi.annotations.AsyncPublisher" annotation 2024-11-03T14:01:40.310+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Scanning for Component classes in com.microdelivery.payment.consumers 2024-11-03T14:01:40.312+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: com.microdelivery.payment.consumers.PaymentRequestConsumer 2024-11-03T14:01:40.313+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Scanning for Component classes in com.microdelivery.payment.consumers 2024-11-03T14:01:40.316+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: com.microdelivery.payment.consumers.PaymentRequestConsumer 2024-11-03T14:01:40.319+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.s.c.a.AnnotationScannerUtil : Scanning class "com.microdelivery.payment.consumers.PaymentRequestConsumer" for @"org.springframework.amqp.rabbit.annotation.RabbitListener" annotation 2024-11-03T14:01:40.320+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Scanning for Component classes in com.microdelivery.payment.consumers 2024-11-03T14:01:40.328+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: com.microdelivery.payment.consumers.PaymentRequestConsumer 2024-11-03T14:01:40.329+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Scanning for Component classes in com.microdelivery.payment.consumers 2024-11-03T14:01:40.333+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: com.microdelivery.payment.consumers.PaymentRequestConsumer 2024-11-03T14:01:40.333+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.s.c.a.AnnotationScannerUtil : Scanning class "com.microdelivery.payment.consumers.PaymentRequestConsumer" for @"org.springframework.amqp.rabbit.annotation.RabbitListener" annotated methods 2024-11-03T14:01:40.334+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.s.c.a.AnnotationScannerUtil : Mapping method "process" 2024-11-03T14:01:40.335+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.s.c.p.i.PayloadExtractor : Finding payload type for PaymentRequestConsumer::process 2024-11-03T14:01:41.494+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] .s.c.a.c.p.ExampleGeneratorPostProcessor : Generate example for com.google.protobuf.ByteString 2024-11-03T14:01:41.494+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.c.e.w.DefaultSchemaWalker : Building example for schema class Schema { type: object format: null $ref: null description: null title: ByteString multipleOf: null maximum: null exclusiveMaximum: null minimum: null exclusiveMinimum: null maxLength: null minLength: null pattern: null maxItems: null minItems: null uniqueItems: null maxProperties: null minProperties: null required: null not: null properties: {empty=class BooleanSchema { class Schema { type: boolean format: null $ref: null description: null title: null multipleOf: null maximum: null exclusiveMaximum: null minimum: null exclusiveMinimum: null maxLength: null minLength: null pattern: null maxItems: null minItems: null uniqueItems: null maxProperties: null minProperties: null required: null not: null properties: null additionalProperties: null nullable: null readOnly: null writeOnly: null example: null externalDocs: null deprecated: null discriminator: null xml: null } }, validUtf8=class BooleanSchema { class Schema { type: boolean format: null $ref: null description: null title: null multipleOf: null maximum: null exclusiveMaximum: null minimum: null exclusiveMinimum: null maxLength: null minLength: null pattern: null maxItems: null minItems: null uniqueItems: null maxProperties: null minProperties: null required: null not: null properties: null additionalProperties: null nullable: null readOnly: null writeOnly: null example: null externalDocs: null deprecated: null discriminator: null xml: null } }} additionalProperties: null nullable: null readOnly: null writeOnly: null example: null externalDocs: null deprecated: null discriminator: null xml: null } 2024-11-03T14:01:41.508+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.c.e.w.DefaultSchemaWalker : Building example for schema class BooleanSchema { class Schema { type: boolean format: null $ref: null description: null title: null multipleOf: null maximum: null exclusiveMaximum: null minimum: null exclusiveMinimum: null maxLength: null minLength: null pattern: null maxItems: null minItems: null uniqueItems: null maxProperties: null minProperties: null required: null not: null properties: null additionalProperties: null nullable: null readOnly: null writeOnly: null example: null externalDocs: null deprecated: null discriminator: null xml: null } } 2024-11-03T14:01:41.512+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.a.c.e.w.DefaultSchemaWalker : Building example for schema class BooleanSchema { class Schema { type: boolean format: null $ref: null description: null title: null multipleOf: null maximum: null exclusiveMaximum: null minimum: null exclusiveMinimum: null maxLength: null minLength: null pattern: null maxItems: null minItems: null uniqueItems: null maxProperties: null minProperties: null required: null not: null properties: null additionalProperties: null nullable: null readOnly: null writeOnly: null example: null externalDocs: null deprecated: null discriminator: null xml: null } } 2024-11-03T14:01:41.519+03:00 DEBUG 18108 --- [MicroDelivery - Payment] [ restartedMain] i.g.s.c.asyncapi.DefaultAsyncApiService : Failed to build AsyncAPI document java.lang.StackOverflowError: null at java.base/java.lang.String.contains(String.java:2854) ~[na:na] at io.github.springwolf.asyncapi.v3.model.channel.message.MessageReference.extractRefName(MessageReference.java:54) ~[springwolf-asyncapi-1.8.0.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:31) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.lambda$removeAvroProperties$0(AvroSchemaPostProcessor.java:49) ~[springwolf-core-1.8.0.jar:na] at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721) ~[na:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:49) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:33) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.lambda$removeAvroProperties$0(AvroSchemaPostProcessor.java:49) ~[springwolf-core-1.8.0.jar:na] at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721) ~[na:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:49) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:33) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.lambda$removeAvroProperties$0(AvroSchemaPostProcessor.java:49) ~[springwolf-core-1.8.0.jar:na] at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721) ~[na:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:49) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:33) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.lambda$removeAvroProperties$0(AvroSchemaPostProcessor.java:49) ~[springwolf-core-1.8.0.jar:na] 2024-11-03T14:01:41.892+03:00 ERROR 18108 --- [MicroDelivery - Payment] [ restartedMain] o.s.boot.SpringApplication : Application run failed java.lang.RuntimeException: Error occured during creation of AsyncAPI at io.github.springwolf.core.asyncapi.DefaultAsyncApiService.getAsyncAPI(DefaultAsyncApiService.java:48) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.SpringwolfInitApplicationListener.onApplicationEvent(SpringwolfInitApplicationListener.java:31) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.SpringwolfInitApplicationListener.onApplicationEvent(SpringwolfInitApplicationListener.java:17) ~[springwolf-core-1.8.0.jar:na] at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:185) ~[spring-context-6.1.14.jar:6.1.14] at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:178) ~[spring-context-6.1.14.jar:6.1.14] at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:156) ~[spring-context-6.1.14.jar:6.1.14] at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:452) ~[spring-context-6.1.14.jar:6.1.14] at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:385) ~[spring-context-6.1.14.jar:6.1.14] at org.springframework.boot.context.event.EventPublishingRunListener.ready(EventPublishingRunListener.java:109) ~[spring-boot-3.3.5.jar:3.3.5] at org.springframework.boot.SpringApplicationRunListeners.lambda$ready$6(SpringApplicationRunListeners.java:80) ~[spring-boot-3.3.5.jar:3.3.5] 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.5.jar:3.3.5] at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:112) ~[spring-boot-3.3.5.jar:3.3.5] at org.springframework.boot.SpringApplicationRunListeners.ready(SpringApplicationRunListeners.java:80) ~[spring-boot-3.3.5.jar:3.3.5] at org.springframework.boot.SpringApplication.run(SpringApplication.java:349) ~[spring-boot-3.3.5.jar:3.3.5] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1363) ~[spring-boot-3.3.5.jar:3.3.5] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1352) ~[spring-boot-3.3.5.jar:3.3.5] at com.microdelivery.payment.PaymentApplicationKt.main(PaymentApplication.kt:13) ~[main/:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na] at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:50) ~[spring-boot-devtools-3.3.5.jar:3.3.5] Caused by: java.lang.StackOverflowError: null at java.base/java.lang.String.contains(String.java:2854) ~[na:na] at io.github.springwolf.asyncapi.v3.model.channel.message.MessageReference.extractRefName(MessageReference.java:54) ~[springwolf-asyncapi-1.8.0.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:31) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.lambda$removeAvroProperties$0(AvroSchemaPostProcessor.java:49) ~[springwolf-core-1.8.0.jar:na] at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721) ~[na:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:49) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:33) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.lambda$removeAvroProperties$0(AvroSchemaPostProcessor.java:49) ~[springwolf-core-1.8.0.jar:na] at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721) ~[na:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:49) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:33) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.lambda$removeAvroProperties$0(AvroSchemaPostProcessor.java:49) ~[springwolf-core-1.8.0.jar:na] Caused by: java.lang.StackOverflowError: null at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721) ~[na:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:49) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:33) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.lambda$removeAvroProperties$0(AvroSchemaPostProcessor.java:49) ~[springwolf-core-1.8.0.jar:na] at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721) ~[na:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:49) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:33) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.lambda$removeAvroProperties$0(AvroSchemaPostProcessor.java:49) ~[springwolf-core-1.8.0.jar:na] at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721) ~[na:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:49) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:33) ~[springwolf-core-1.8.0.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.lambda$removeAvroProperties$0(AvroSchemaPostProcessor.java:49) ~[springwolf-core-1.8.0.jar:na] ```

PaymentResponse class is generated using ProtoBuf schema so it would be difficult to read generated mess :x It also extends GeneratedMessage class available here Here is my protobuf definition as well as PaymentResponse class generated from this definition:

payment.proto ``` syntax = "proto3"; package model; option java_package = "com.microdelivery.model"; message PaymentRequest { int32 id = 1; int32 userId = 2; string paymentMethod = 3; repeated Good goods = 4; } message Good { int32 id = 1; uint64 price = 2; } message PaymentResponse { int32 id = 1; Status status = 2; string redirectUrl = 3; enum Status { SUCCESSFUL = 0; FAILED = 1; ABORTED = 2; UNAVAILABLE = 3; } } ```
Generated PaymentResponse class ```java public static final class PaymentResponse extends com.google.protobuf.GeneratedMessage implements // @@protoc_insertion_point(message_implements:model.PaymentResponse) PaymentResponseOrBuilder { private static final long serialVersionUID = 0L; static { com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion( com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, /* minor= */ 28, /* patch= */ 3, /* suffix= */ "", PaymentResponse.class.getName()); } // Use PaymentResponse.newBuilder() to construct. private PaymentResponse(com.google.protobuf.GeneratedMessage.Builder builder) { super(builder); } private PaymentResponse() { status_ = 0; redirectUrl_ = ""; } public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { return com.microdelivery.model.Payment.internal_static_model_PaymentResponse_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { return com.microdelivery.model.Payment.internal_static_model_PaymentResponse_fieldAccessorTable .ensureFieldAccessorsInitialized( com.microdelivery.model.Payment.PaymentResponse.class, com.microdelivery.model.Payment.PaymentResponse.Builder.class); } /** * Protobuf enum {@code model.PaymentResponse.Status} */ public enum Status implements com.google.protobuf.ProtocolMessageEnum { /** * SUCCESSFUL = 0; */ SUCCESSFUL(0), /** * FAILED = 1; */ FAILED(1), /** * ABORTED = 2; */ ABORTED(2), /** * UNAVAILABLE = 3; */ UNAVAILABLE(3), UNRECOGNIZED(-1), ; static { com.google.protobuf.RuntimeVersion.validateProtobufGencodeVersion( com.google.protobuf.RuntimeVersion.RuntimeDomain.PUBLIC, /* major= */ 4, /* minor= */ 28, /* patch= */ 3, /* suffix= */ "", Status.class.getName()); } /** * SUCCESSFUL = 0; */ public static final int SUCCESSFUL_VALUE = 0; /** * FAILED = 1; */ public static final int FAILED_VALUE = 1; /** * ABORTED = 2; */ public static final int ABORTED_VALUE = 2; /** * UNAVAILABLE = 3; */ public static final int UNAVAILABLE_VALUE = 3; public final int getNumber() { if (this == UNRECOGNIZED) { throw new java.lang.IllegalArgumentException( "Can't get the number of an unknown enum value."); } return value; } /** * @param value The numeric wire value of the corresponding enum entry. * @return The enum associated with the given numeric wire value. * @deprecated Use {@link #forNumber(int)} instead. */ @java.lang.Deprecated public static Status valueOf(int value) { return forNumber(value); } /** * @param value The numeric wire value of the corresponding enum entry. * @return The enum associated with the given numeric wire value. */ public static Status forNumber(int value) { switch (value) { case 0: return SUCCESSFUL; case 1: return FAILED; case 2: return ABORTED; case 3: return UNAVAILABLE; default: return null; } } public static com.google.protobuf.Internal.EnumLiteMap internalGetValueMap() { return internalValueMap; } private static final com.google.protobuf.Internal.EnumLiteMap< Status> internalValueMap = new com.google.protobuf.Internal.EnumLiteMap() { public Status findValueByNumber(int number) { return Status.forNumber(number); } }; public final com.google.protobuf.Descriptors.EnumValueDescriptor getValueDescriptor() { if (this == UNRECOGNIZED) { throw new java.lang.IllegalStateException( "Can't get the descriptor of an unrecognized enum value."); } return getDescriptor().getValues().get(ordinal()); } public final com.google.protobuf.Descriptors.EnumDescriptor getDescriptorForType() { return getDescriptor(); } public static final com.google.protobuf.Descriptors.EnumDescriptor getDescriptor() { return com.microdelivery.model.Payment.PaymentResponse.getDescriptor().getEnumTypes().get(0); } private static final Status[] VALUES = values(); public static Status valueOf( com.google.protobuf.Descriptors.EnumValueDescriptor desc) { if (desc.getType() != getDescriptor()) { throw new java.lang.IllegalArgumentException( "EnumValueDescriptor is not for this type."); } if (desc.getIndex() == -1) { return UNRECOGNIZED; } return VALUES[desc.getIndex()]; } private final int value; private Status(int value) { this.value = value; } // @@protoc_insertion_point(enum_scope:model.PaymentResponse.Status) } public static final int ID_FIELD_NUMBER = 1; private int id_ = 0; /** * int32 id = 1; * @return The id. */ @java.lang.Override public int getId() { return id_; } public static final int STATUS_FIELD_NUMBER = 2; private int status_ = 0; /** * .model.PaymentResponse.Status status = 2; * @return The enum numeric value on the wire for status. */ @java.lang.Override public int getStatusValue() { return status_; } /** * .model.PaymentResponse.Status status = 2; * @return The status. */ @java.lang.Override public com.microdelivery.model.Payment.PaymentResponse.Status getStatus() { com.microdelivery.model.Payment.PaymentResponse.Status result = com.microdelivery.model.Payment.PaymentResponse.Status.forNumber(status_); return result == null ? com.microdelivery.model.Payment.PaymentResponse.Status.UNRECOGNIZED : result; } public static final int REDIRECTURL_FIELD_NUMBER = 3; @SuppressWarnings("serial") private volatile java.lang.Object redirectUrl_ = ""; /** * string redirectUrl = 3; * @return The redirectUrl. */ @java.lang.Override public java.lang.String getRedirectUrl() { java.lang.Object ref = redirectUrl_; if (ref instanceof java.lang.String) { return (java.lang.String) ref; } else { com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; java.lang.String s = bs.toStringUtf8(); redirectUrl_ = s; return s; } } /** * string redirectUrl = 3; * @return The bytes for redirectUrl. */ @java.lang.Override public com.google.protobuf.ByteString getRedirectUrlBytes() { java.lang.Object ref = redirectUrl_; if (ref instanceof java.lang.String) { com.google.protobuf.ByteString b = com.google.protobuf.ByteString.copyFromUtf8( (java.lang.String) ref); redirectUrl_ = b; return b; } else { return (com.google.protobuf.ByteString) ref; } } private byte memoizedIsInitialized = -1; @java.lang.Override public final boolean isInitialized() { byte isInitialized = memoizedIsInitialized; if (isInitialized == 1) return true; if (isInitialized == 0) return false; memoizedIsInitialized = 1; return true; } @java.lang.Override public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException { if (id_ != 0) { output.writeInt32(1, id_); } if (status_ != com.microdelivery.model.Payment.PaymentResponse.Status.SUCCESSFUL.getNumber()) { output.writeEnum(2, status_); } if (!com.google.protobuf.GeneratedMessage.isStringEmpty(redirectUrl_)) { com.google.protobuf.GeneratedMessage.writeString(output, 3, redirectUrl_); } getUnknownFields().writeTo(output); } @java.lang.Override public int getSerializedSize() { int size = memoizedSize; if (size != -1) return size; size = 0; if (id_ != 0) { size += com.google.protobuf.CodedOutputStream .computeInt32Size(1, id_); } if (status_ != com.microdelivery.model.Payment.PaymentResponse.Status.SUCCESSFUL.getNumber()) { size += com.google.protobuf.CodedOutputStream .computeEnumSize(2, status_); } if (!com.google.protobuf.GeneratedMessage.isStringEmpty(redirectUrl_)) { size += com.google.protobuf.GeneratedMessage.computeStringSize(3, redirectUrl_); } size += getUnknownFields().getSerializedSize(); memoizedSize = size; return size; } @java.lang.Override public boolean equals(final java.lang.Object obj) { if (obj == this) { return true; } if (!(obj instanceof com.microdelivery.model.Payment.PaymentResponse)) { return super.equals(obj); } com.microdelivery.model.Payment.PaymentResponse other = (com.microdelivery.model.Payment.PaymentResponse) obj; if (getId() != other.getId()) return false; if (status_ != other.status_) return false; if (!getRedirectUrl() .equals(other.getRedirectUrl())) return false; if (!getUnknownFields().equals(other.getUnknownFields())) return false; return true; } @java.lang.Override public int hashCode() { if (memoizedHashCode != 0) { return memoizedHashCode; } int hash = 41; hash = (19 * hash) + getDescriptor().hashCode(); hash = (37 * hash) + ID_FIELD_NUMBER; hash = (53 * hash) + getId(); hash = (37 * hash) + STATUS_FIELD_NUMBER; hash = (53 * hash) + status_; hash = (37 * hash) + REDIRECTURL_FIELD_NUMBER; hash = (53 * hash) + getRedirectUrl().hashCode(); hash = (29 * hash) + getUnknownFields().hashCode(); memoizedHashCode = hash; return hash; } public static com.microdelivery.model.Payment.PaymentResponse parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static com.microdelivery.model.Payment.PaymentResponse parseFrom( java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static com.microdelivery.model.Payment.PaymentResponse parseFrom( com.google.protobuf.ByteString data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static com.microdelivery.model.Payment.PaymentResponse parseFrom( com.google.protobuf.ByteString data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static com.microdelivery.model.Payment.PaymentResponse parseFrom(byte[] data) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data); } public static com.microdelivery.model.Payment.PaymentResponse parseFrom( byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { return PARSER.parseFrom(data, extensionRegistry); } public static com.microdelivery.model.Payment.PaymentResponse parseFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } public static com.microdelivery.model.Payment.PaymentResponse parseFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input, extensionRegistry); } public static com.microdelivery.model.Payment.PaymentResponse parseDelimitedFrom(java.io.InputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input); } public static com.microdelivery.model.Payment.PaymentResponse parseDelimitedFrom( java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseDelimitedWithIOException(PARSER, input, extensionRegistry); } public static com.microdelivery.model.Payment.PaymentResponse parseFrom( com.google.protobuf.CodedInputStream input) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input); } public static com.microdelivery.model.Payment.PaymentResponse parseFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { return com.google.protobuf.GeneratedMessage .parseWithIOException(PARSER, input, extensionRegistry); } @java.lang.Override public Builder newBuilderForType() { return newBuilder(); } public static Builder newBuilder() { return DEFAULT_INSTANCE.toBuilder(); } public static Builder newBuilder(com.microdelivery.model.Payment.PaymentResponse prototype) { return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); } @java.lang.Override public Builder toBuilder() { return this == DEFAULT_INSTANCE ? new Builder() : new Builder().mergeFrom(this); } @java.lang.Override protected Builder newBuilderForType( com.google.protobuf.GeneratedMessage.BuilderParent parent) { Builder builder = new Builder(parent); return builder; } /** * Protobuf type {@code model.PaymentResponse} */ public static final class Builder extends com.google.protobuf.GeneratedMessage.Builder implements // @@protoc_insertion_point(builder_implements:model.PaymentResponse) com.microdelivery.model.Payment.PaymentResponseOrBuilder { public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { return com.microdelivery.model.Payment.internal_static_model_PaymentResponse_descriptor; } @java.lang.Override protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() { return com.microdelivery.model.Payment.internal_static_model_PaymentResponse_fieldAccessorTable .ensureFieldAccessorsInitialized( com.microdelivery.model.Payment.PaymentResponse.class, com.microdelivery.model.Payment.PaymentResponse.Builder.class); } // Construct using com.microdelivery.model.Payment.PaymentResponse.newBuilder() private Builder() { } private Builder( com.google.protobuf.GeneratedMessage.BuilderParent parent) { super(parent); } @java.lang.Override public Builder clear() { super.clear(); bitField0_ = 0; id_ = 0; status_ = 0; redirectUrl_ = ""; return this; } @java.lang.Override public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() { return com.microdelivery.model.Payment.internal_static_model_PaymentResponse_descriptor; } @java.lang.Override public com.microdelivery.model.Payment.PaymentResponse getDefaultInstanceForType() { return com.microdelivery.model.Payment.PaymentResponse.getDefaultInstance(); } @java.lang.Override public com.microdelivery.model.Payment.PaymentResponse build() { com.microdelivery.model.Payment.PaymentResponse result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } return result; } @java.lang.Override public com.microdelivery.model.Payment.PaymentResponse buildPartial() { com.microdelivery.model.Payment.PaymentResponse result = new com.microdelivery.model.Payment.PaymentResponse(this); if (bitField0_ != 0) { buildPartial0(result); } onBuilt(); return result; } private void buildPartial0(com.microdelivery.model.Payment.PaymentResponse result) { int from_bitField0_ = bitField0_; if (((from_bitField0_ & 0x00000001) != 0)) { result.id_ = id_; } if (((from_bitField0_ & 0x00000002) != 0)) { result.status_ = status_; } if (((from_bitField0_ & 0x00000004) != 0)) { result.redirectUrl_ = redirectUrl_; } } @java.lang.Override public Builder mergeFrom(com.google.protobuf.Message other) { if (other instanceof com.microdelivery.model.Payment.PaymentResponse) { return mergeFrom((com.microdelivery.model.Payment.PaymentResponse)other); } else { super.mergeFrom(other); return this; } } public Builder mergeFrom(com.microdelivery.model.Payment.PaymentResponse other) { if (other == com.microdelivery.model.Payment.PaymentResponse.getDefaultInstance()) return this; if (other.getId() != 0) { setId(other.getId()); } if (other.status_ != 0) { setStatusValue(other.getStatusValue()); } if (!other.getRedirectUrl().isEmpty()) { redirectUrl_ = other.redirectUrl_; bitField0_ |= 0x00000004; onChanged(); } this.mergeUnknownFields(other.getUnknownFields()); onChanged(); return this; } @java.lang.Override public final boolean isInitialized() { return true; } @java.lang.Override public Builder mergeFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException { if (extensionRegistry == null) { throw new java.lang.NullPointerException(); } try { boolean done = false; while (!done) { int tag = input.readTag(); switch (tag) { case 0: done = true; break; case 8: { id_ = input.readInt32(); bitField0_ |= 0x00000001; break; } // case 8 case 16: { status_ = input.readEnum(); bitField0_ |= 0x00000002; break; } // case 16 case 26: { redirectUrl_ = input.readStringRequireUtf8(); bitField0_ |= 0x00000004; break; } // case 26 default: { if (!super.parseUnknownField(input, extensionRegistry, tag)) { done = true; // was an endgroup tag } break; } // default: } // switch (tag) } // while (!done) } catch (com.google.protobuf.InvalidProtocolBufferException e) { throw e.unwrapIOException(); } finally { onChanged(); } // finally return this; } private int bitField0_; private int id_ ; /** * int32 id = 1; * @return The id. */ @java.lang.Override public int getId() { return id_; } /** * int32 id = 1; * @param value The id to set. * @return This builder for chaining. */ public Builder setId(int value) { id_ = value; bitField0_ |= 0x00000001; onChanged(); return this; } /** * int32 id = 1; * @return This builder for chaining. */ public Builder clearId() { bitField0_ = (bitField0_ & ~0x00000001); id_ = 0; onChanged(); return this; } private int status_ = 0; /** * .model.PaymentResponse.Status status = 2; * @return The enum numeric value on the wire for status. */ @java.lang.Override public int getStatusValue() { return status_; } /** * .model.PaymentResponse.Status status = 2; * @param value The enum numeric value on the wire for status to set. * @return This builder for chaining. */ public Builder setStatusValue(int value) { status_ = value; bitField0_ |= 0x00000002; onChanged(); return this; } /** * .model.PaymentResponse.Status status = 2; * @return The status. */ @java.lang.Override public com.microdelivery.model.Payment.PaymentResponse.Status getStatus() { com.microdelivery.model.Payment.PaymentResponse.Status result = com.microdelivery.model.Payment.PaymentResponse.Status.forNumber(status_); return result == null ? com.microdelivery.model.Payment.PaymentResponse.Status.UNRECOGNIZED : result; } /** * .model.PaymentResponse.Status status = 2; * @param value The status to set. * @return This builder for chaining. */ public Builder setStatus(com.microdelivery.model.Payment.PaymentResponse.Status value) { if (value == null) { throw new NullPointerException(); } bitField0_ |= 0x00000002; status_ = value.getNumber(); onChanged(); return this; } /** * .model.PaymentResponse.Status status = 2; * @return This builder for chaining. */ public Builder clearStatus() { bitField0_ = (bitField0_ & ~0x00000002); status_ = 0; onChanged(); return this; } private java.lang.Object redirectUrl_ = ""; /** * string redirectUrl = 3; * @return The redirectUrl. */ public java.lang.String getRedirectUrl() { java.lang.Object ref = redirectUrl_; if (!(ref instanceof java.lang.String)) { com.google.protobuf.ByteString bs = (com.google.protobuf.ByteString) ref; java.lang.String s = bs.toStringUtf8(); redirectUrl_ = s; return s; } else { return (java.lang.String) ref; } } /** * string redirectUrl = 3; * @return The bytes for redirectUrl. */ public com.google.protobuf.ByteString getRedirectUrlBytes() { java.lang.Object ref = redirectUrl_; if (ref instanceof String) { com.google.protobuf.ByteString b = com.google.protobuf.ByteString.copyFromUtf8( (java.lang.String) ref); redirectUrl_ = b; return b; } else { return (com.google.protobuf.ByteString) ref; } } /** * string redirectUrl = 3; * @param value The redirectUrl to set. * @return This builder for chaining. */ public Builder setRedirectUrl( java.lang.String value) { if (value == null) { throw new NullPointerException(); } redirectUrl_ = value; bitField0_ |= 0x00000004; onChanged(); return this; } /** * string redirectUrl = 3; * @return This builder for chaining. */ public Builder clearRedirectUrl() { redirectUrl_ = getDefaultInstance().getRedirectUrl(); bitField0_ = (bitField0_ & ~0x00000004); onChanged(); return this; } /** * string redirectUrl = 3; * @param value The bytes for redirectUrl to set. * @return This builder for chaining. */ public Builder setRedirectUrlBytes( com.google.protobuf.ByteString value) { if (value == null) { throw new NullPointerException(); } checkByteStringIsUtf8(value); redirectUrl_ = value; bitField0_ |= 0x00000004; onChanged(); return this; } // @@protoc_insertion_point(builder_scope:model.PaymentResponse) } // @@protoc_insertion_point(class_scope:model.PaymentResponse) private static final com.microdelivery.model.Payment.PaymentResponse DEFAULT_INSTANCE; static { DEFAULT_INSTANCE = new com.microdelivery.model.Payment.PaymentResponse(); } public static com.microdelivery.model.Payment.PaymentResponse getDefaultInstance() { return DEFAULT_INSTANCE; } private static final com.google.protobuf.Parser PARSER = new com.google.protobuf.AbstractParser() { @java.lang.Override public PaymentResponse parsePartialFrom( com.google.protobuf.CodedInputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws com.google.protobuf.InvalidProtocolBufferException { Builder builder = newBuilder(); try { builder.mergeFrom(input, extensionRegistry); } catch (com.google.protobuf.InvalidProtocolBufferException e) { throw e.setUnfinishedMessage(builder.buildPartial()); } catch (com.google.protobuf.UninitializedMessageException e) { throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); } catch (java.io.IOException e) { throw new com.google.protobuf.InvalidProtocolBufferException(e) .setUnfinishedMessage(builder.buildPartial()); } return builder.buildPartial(); } }; public static com.google.protobuf.Parser parser() { return PARSER; } @java.lang.Override public com.google.protobuf.Parser getParserForType() { return PARSER; } @java.lang.Override public com.microdelivery.model.Payment.PaymentResponse getDefaultInstanceForType() { return DEFAULT_INSTANCE; } } ```

To generate this mess I'm using com.google.protobuf:protobuf-kotlin:4.28.3 I'm using ProtoBuf because I need to communicate with other microservices written in other languages (for our university project). It generates classes automatically using same format (.proto files) for everyone. If you happen to know what else I can use to achieve something like that - I'd like to know c:

timonback commented 1 day ago

Thank you, we will have to look into it. Actually, on second thought, it is interesting that the protobuf causes a stackoverflow for avro, which is different wire protocol.

In case you want to experiment, debug and contribute: We have a basic protobuf example project, probably with similar dependencies: https://github.com/springwolf/springwolf-core/blob/master/springwolf-examples%2Fspringwolf-kafka-example%2Fsrc%2Fmain%2Fproto%2FExamplePayloadProtobufDto.proto Just fork springwolf-core, put your proto file inside the file above and create a consumer/producer as you have done. Whether it is kafka or rabbitmq likely does not matter for this.

slava110 commented 1 day ago

Hi. I've tested both my and your schema in https://github.com/springwolf/springwolf-core/tree/master/springwolf-examples/springwolf-amqp-example project I've added protobuf dependencies from kafka module, copied your proto from kafka module, tried running the server, copied my own proto, tried running the server again. It didn't produce error immediately, however, it crashed after some time (or maybe after some time after I try to access docs endpoint? Probably not). It produces a bit different error, but it is also related to StackOverflow and Avro removeProperties (but more similar to this one somehow: https://github.com/springwolf/springwolf-core/issues/830 (although, it's probably unrelated, since author said it's their generator's issue or something)).

Log ``` 2024-11-04T00:28:14.045+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] .g.s.c.SpringwolfInitApplicationListener : Triggering asyncapi creation 2024-11-04T00:28:14.045+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.asyncapi.DefaultAsyncApiService : Building AsyncAPI document 2024-11-04T00:28:14.047+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Scanning for Component classes in io.github.springwolf.examples.amqp 2024-11-04T00:28:14.090+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: io.github.springwolf.examples.amqp.configuration.RabbitConfiguration 2024-11-04T00:28:14.090+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: io.github.springwolf.examples.amqp.configuration.RabbitMqReadinessVerifier 2024-11-04T00:28:14.090+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: io.github.springwolf.examples.amqp.consumers.ExampleConsumer 2024-11-04T00:28:14.090+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: io.github.springwolf.examples.amqp.producers.AnotherProducer 2024-11-04T00:28:14.090+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: io.github.springwolf.examples.amqp.SpringwolfAmqpExampleApplication 2024-11-04T00:28:14.090+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Scanning for Component classes in io.github.springwolf.examples.amqp 2024-11-04T00:28:14.101+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: io.github.springwolf.examples.amqp.configuration.RabbitConfiguration 2024-11-04T00:28:14.101+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: io.github.springwolf.examples.amqp.configuration.RabbitMqReadinessVerifier 2024-11-04T00:28:14.101+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: io.github.springwolf.examples.amqp.consumers.ExampleConsumer 2024-11-04T00:28:14.101+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: io.github.springwolf.examples.amqp.producers.AnotherProducer 2024-11-04T00:28:14.101+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: io.github.springwolf.examples.amqp.SpringwolfAmqpExampleApplication 2024-11-04T00:28:14.105+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.a.AnnotationScannerUtil : Scanning class "org.springframework.amqp.support.converter.Jackson2JsonMessageConverter" for @"io.github.springwolf.core.asyncapi.annotations.AsyncListener" annotated methods 2024-11-04T00:28:14.108+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.a.AnnotationScannerUtil : Scanning class "org.springframework.amqp.core.Exchange" for @"io.github.springwolf.core.asyncapi.annotations.AsyncListener" annotated methods 2024-11-04T00:28:14.108+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.a.AnnotationScannerUtil : Scanning class "org.springframework.amqp.core.Binding" for @"io.github.springwolf.core.asyncapi.annotations.AsyncListener" annotated methods 2024-11-04T00:28:14.109+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.a.AnnotationScannerUtil : Scanning class "org.springframework.amqp.core.Queue" for @"io.github.springwolf.core.asyncapi.annotations.AsyncListener" annotated methods 2024-11-04T00:28:14.109+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.a.AnnotationScannerUtil : Scanning class "io.github.springwolf.examples.amqp.producers.AnotherProducer" for @"io.github.springwolf.core.asyncapi.annotations.AsyncListener" annotated methods 2024-11-04T00:28:14.109+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.a.AnnotationScannerUtil : Scanning class "io.github.springwolf.examples.amqp.consumers.ExampleConsumer" for @"io.github.springwolf.core.asyncapi.annotations.AsyncListener" annotated methods 2024-11-04T00:28:14.109+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.a.AnnotationScannerUtil : Scanning class "io.github.springwolf.examples.amqp.configuration.RabbitMqReadinessVerifier" for @"io.github.springwolf.core.asyncapi.annotations.AsyncListener" annotated methods 2024-11-04T00:28:14.109+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.a.AnnotationScannerUtil : Scanning class "io.github.springwolf.examples.amqp.configuration.RabbitConfiguration" for @"io.github.springwolf.core.asyncapi.annotations.AsyncListener" annotated methods 2024-11-04T00:28:14.109+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.a.AnnotationScannerUtil : Scanning class "io.github.springwolf.examples.amqp.SpringwolfAmqpExampleApplication" for @"io.github.springwolf.core.asyncapi.annotations.AsyncListener" annotated methods 2024-11-04T00:28:14.111+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Scanning for Component classes in io.github.springwolf.examples.amqp 2024-11-04T00:28:14.120+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: io.github.springwolf.examples.amqp.configuration.RabbitConfiguration 2024-11-04T00:28:14.120+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: io.github.springwolf.examples.amqp.configuration.RabbitMqReadinessVerifier 2024-11-04T00:28:14.120+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: io.github.springwolf.examples.amqp.consumers.ExampleConsumer 2024-11-04T00:28:14.121+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: io.github.springwolf.examples.amqp.producers.AnotherProducer 2024-11-04T00:28:14.121+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: io.github.springwolf.examples.amqp.SpringwolfAmqpExampleApplication 2024-11-04T00:28:14.121+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Scanning for Component classes in io.github.springwolf.examples.amqp 2024-11-04T00:28:14.130+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: io.github.springwolf.examples.amqp.configuration.RabbitConfiguration 2024-11-04T00:28:14.130+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: io.github.springwolf.examples.amqp.configuration.RabbitMqReadinessVerifier 2024-11-04T00:28:14.130+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: io.github.springwolf.examples.amqp.consumers.ExampleConsumer 2024-11-04T00:28:14.130+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: io.github.springwolf.examples.amqp.producers.AnotherProducer 2024-11-04T00:28:14.130+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: io.github.springwolf.examples.amqp.SpringwolfAmqpExampleApplication 2024-11-04T00:28:14.131+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.a.AnnotationScannerUtil : Scanning class "org.springframework.amqp.support.converter.Jackson2JsonMessageConverter" for @"io.github.springwolf.core.asyncapi.annotations.AsyncListener" annotation 2024-11-04T00:28:14.131+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.a.AnnotationScannerUtil : Scanning class "org.springframework.amqp.core.Exchange" for @"io.github.springwolf.core.asyncapi.annotations.AsyncListener" annotation 2024-11-04T00:28:14.131+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.a.AnnotationScannerUtil : Scanning class "org.springframework.amqp.core.Binding" for @"io.github.springwolf.core.asyncapi.annotations.AsyncListener" annotation 2024-11-04T00:28:14.131+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.a.AnnotationScannerUtil : Scanning class "org.springframework.amqp.core.Queue" for @"io.github.springwolf.core.asyncapi.annotations.AsyncListener" annotation 2024-11-04T00:28:14.132+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.a.AnnotationScannerUtil : Scanning class "io.github.springwolf.examples.amqp.producers.AnotherProducer" for @"io.github.springwolf.core.asyncapi.annotations.AsyncListener" annotation 2024-11-04T00:28:14.132+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.a.AnnotationScannerUtil : Scanning class "io.github.springwolf.examples.amqp.consumers.ExampleConsumer" for @"io.github.springwolf.core.asyncapi.annotations.AsyncListener" annotation 2024-11-04T00:28:14.132+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.a.AnnotationScannerUtil : Scanning class "io.github.springwolf.examples.amqp.configuration.RabbitMqReadinessVerifier" for @"io.github.springwolf.core.asyncapi.annotations.AsyncListener" annotation 2024-11-04T00:28:14.132+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.a.AnnotationScannerUtil : Scanning class "io.github.springwolf.examples.amqp.configuration.RabbitConfiguration" for @"io.github.springwolf.core.asyncapi.annotations.AsyncListener" annotation 2024-11-04T00:28:14.132+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.a.AnnotationScannerUtil : Scanning class "io.github.springwolf.examples.amqp.SpringwolfAmqpExampleApplication" for @"io.github.springwolf.core.asyncapi.annotations.AsyncListener" annotation 2024-11-04T00:28:14.132+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Scanning for Component classes in io.github.springwolf.examples.amqp 2024-11-04T00:28:14.146+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: io.github.springwolf.examples.amqp.configuration.RabbitConfiguration 2024-11-04T00:28:14.146+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: io.github.springwolf.examples.amqp.configuration.RabbitMqReadinessVerifier 2024-11-04T00:28:14.146+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: io.github.springwolf.examples.amqp.consumers.ExampleConsumer 2024-11-04T00:28:14.146+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: io.github.springwolf.examples.amqp.producers.AnotherProducer 2024-11-04T00:28:14.146+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: io.github.springwolf.examples.amqp.SpringwolfAmqpExampleApplication 2024-11-04T00:28:14.146+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Scanning for Component classes in io.github.springwolf.examples.amqp 2024-11-04T00:28:14.164+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: io.github.springwolf.examples.amqp.configuration.RabbitConfiguration 2024-11-04T00:28:14.164+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: io.github.springwolf.examples.amqp.configuration.RabbitMqReadinessVerifier 2024-11-04T00:28:14.164+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: io.github.springwolf.examples.amqp.consumers.ExampleConsumer 2024-11-04T00:28:14.164+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: io.github.springwolf.examples.amqp.producers.AnotherProducer 2024-11-04T00:28:14.164+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.s.a.AnnotationClassScanner : Found candidate class: io.github.springwolf.examples.amqp.SpringwolfAmqpExampleApplication 2024-11-04T00:28:14.165+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.a.AnnotationScannerUtil : Scanning class "org.springframework.amqp.support.converter.Jackson2JsonMessageConverter" for @"io.github.springwolf.core.asyncapi.annotations.AsyncPublisher" annotated methods 2024-11-04T00:28:14.166+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.a.AnnotationScannerUtil : Scanning class "org.springframework.amqp.core.Exchange" for @"io.github.springwolf.core.asyncapi.annotations.AsyncPublisher" annotated methods 2024-11-04T00:28:14.168+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.a.AnnotationScannerUtil : Scanning class "org.springframework.amqp.core.Binding" for @"io.github.springwolf.core.asyncapi.annotations.AsyncPublisher" annotated methods 2024-11-04T00:28:14.168+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.a.AnnotationScannerUtil : Scanning class "org.springframework.amqp.core.Queue" for @"io.github.springwolf.core.asyncapi.annotations.AsyncPublisher" annotated methods 2024-11-04T00:28:14.169+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.a.AnnotationScannerUtil : Scanning class "io.github.springwolf.examples.amqp.producers.AnotherProducer" for @"io.github.springwolf.core.asyncapi.annotations.AsyncPublisher" annotated methods 2024-11-04T00:28:14.170+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.a.AnnotationScannerUtil : Mapping method "sendMessage" 2024-11-04T00:28:14.175+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.s.c.p.i.PayloadExtractor : Finding payload type for AnotherProducer::sendMessage 2024-11-04T00:28:15.179+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] .s.c.a.c.p.ExampleGeneratorPostProcessor : Generate example for com.google.protobuf.ByteString 2024-11-04T00:28:15.180+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.c.e.w.DefaultSchemaWalker : Building example for schema class Schema { type: object format: null $ref: null description: null title: ByteString multipleOf: null maximum: null exclusiveMaximum: null minimum: null exclusiveMinimum: null maxLength: null minLength: null pattern: null maxItems: null minItems: null uniqueItems: null maxProperties: null minProperties: null required: null not: null properties: {empty=class BooleanSchema { class Schema { type: boolean format: null $ref: null description: null title: null multipleOf: null maximum: null exclusiveMaximum: null minimum: null exclusiveMinimum: null maxLength: null minLength: null pattern: null maxItems: null minItems: null uniqueItems: null maxProperties: null minProperties: null required: null not: null properties: null additionalProperties: null nullable: null readOnly: null writeOnly: null example: null externalDocs: null deprecated: null discriminator: null xml: null } }, validUtf8=class BooleanSchema { class Schema { type: boolean format: null $ref: null description: null title: null multipleOf: null maximum: null exclusiveMaximum: null minimum: null exclusiveMinimum: null maxLength: null minLength: null pattern: null maxItems: null minItems: null uniqueItems: null maxProperties: null minProperties: null required: null not: null properties: null additionalProperties: null nullable: null readOnly: null writeOnly: null example: null externalDocs: null deprecated: null discriminator: null xml: null } }} additionalProperties: null nullable: null readOnly: null writeOnly: null example: null externalDocs: null deprecated: null discriminator: null xml: null } 2024-11-04T00:28:15.181+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.c.e.w.DefaultSchemaWalker : Building example for schema class BooleanSchema { class Schema { type: boolean format: null $ref: null description: null title: null multipleOf: null maximum: null exclusiveMaximum: null minimum: null exclusiveMinimum: null maxLength: null minLength: null pattern: null maxItems: null minItems: null uniqueItems: null maxProperties: null minProperties: null required: null not: null properties: null additionalProperties: null nullable: null readOnly: null writeOnly: null example: null externalDocs: null deprecated: null discriminator: null xml: null } } 2024-11-04T00:28:15.183+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.a.c.e.w.DefaultSchemaWalker : Building example for schema class BooleanSchema { class Schema { type: boolean format: null $ref: null description: null title: null multipleOf: null maximum: null exclusiveMaximum: null minimum: null exclusiveMinimum: null maxLength: null minLength: null pattern: null maxItems: null minItems: null uniqueItems: null maxProperties: null minProperties: null required: null not: null properties: null additionalProperties: null nullable: null readOnly: null writeOnly: null example: null externalDocs: null deprecated: null discriminator: null xml: null } } 2024-11-04T00:28:15.190+03:00 DEBUG 16064 --- [Springwolf example project - AMQP] [ main] i.g.s.c.asyncapi.DefaultAsyncApiService : Failed to build AsyncAPI document java.lang.StackOverflowError: null at java.base/java.util.HashMap.hash(HashMap.java:338) ~[na:na] at java.base/java.util.HashMap.getNode(HashMap.java:568) ~[na:na] at java.base/java.util.LinkedHashMap.getOrDefault(LinkedHashMap.java:453) ~[na:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:39) ~[springwolf-core.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:33) ~[springwolf-core.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.lambda$removeAvroProperties$0(AvroSchemaPostProcessor.java:49) ~[springwolf-core.jar:na] at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721) ~[na:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:49) ~[springwolf-core.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:33) ~[springwolf-core.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.lambda$removeAvroProperties$0(AvroSchemaPostProcessor.java:49) ~[springwolf-core.jar:na] at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721) ~[na:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:49) ~[springwolf-core.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:33) ~[springwolf-core.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.lambda$removeAvroProperties$0(AvroSchemaPostProcessor.java:49) ~[springwolf-core.jar:na] at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721) ~[na:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:49) ~[springwolf-core.jar:na] 2024-11-04T00:28:15.288+03:00 ERROR 16064 --- [Springwolf example project - AMQP] [ main] o.s.boot.SpringApplication : Application run failed java.lang.RuntimeException: Error occured during creation of AsyncAPI at io.github.springwolf.core.asyncapi.DefaultAsyncApiService.getAsyncAPI(DefaultAsyncApiService.java:48) ~[springwolf-core.jar:na] at io.github.springwolf.core.SpringwolfInitApplicationListener.onApplicationEvent(SpringwolfInitApplicationListener.java:31) ~[springwolf-core.jar:na] at io.github.springwolf.core.SpringwolfInitApplicationListener.onApplicationEvent(SpringwolfInitApplicationListener.java:17) ~[springwolf-core.jar:na] at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:185) ~[spring-context-6.1.13.jar:6.1.13] at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:178) ~[spring-context-6.1.13.jar:6.1.13] at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:156) ~[spring-context-6.1.13.jar:6.1.13] at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:452) ~[spring-context-6.1.13.jar:6.1.13] at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:385) ~[spring-context-6.1.13.jar:6.1.13] at org.springframework.boot.context.event.EventPublishingRunListener.ready(EventPublishingRunListener.java:109) ~[spring-boot-3.3.4.jar:3.3.4] at org.springframework.boot.SpringApplicationRunListeners.lambda$ready$6(SpringApplicationRunListeners.java:80) ~[spring-boot-3.3.4.jar:3.3.4] 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.4.jar:3.3.4] at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:112) ~[spring-boot-3.3.4.jar:3.3.4] at org.springframework.boot.SpringApplicationRunListeners.ready(SpringApplicationRunListeners.java:80) ~[spring-boot-3.3.4.jar:3.3.4] at org.springframework.boot.SpringApplication.run(SpringApplication.java:349) ~[spring-boot-3.3.4.jar:3.3.4] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1363) ~[spring-boot-3.3.4.jar:3.3.4] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1352) ~[spring-boot-3.3.4.jar:3.3.4] at io.github.springwolf.examples.amqp.SpringwolfAmqpExampleApplication.main(SpringwolfAmqpExampleApplication.java:11) ~[main/:na] Caused by: java.lang.StackOverflowError: null at java.base/java.util.HashMap.hash(HashMap.java:338) ~[na:na] at java.base/java.util.HashMap.getNode(HashMap.java:568) ~[na:na] at java.base/java.util.LinkedHashMap.getOrDefault(LinkedHashMap.java:453) ~[na:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:39) ~[springwolf-core.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:33) ~[springwolf-core.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.lambda$removeAvroProperties$0(AvroSchemaPostProcessor.java:49) ~[springwolf-core.jar:na] at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721) ~[na:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:49) ~[springwolf-core.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:33) ~[springwolf-core.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.lambda$removeAvroProperties$0(AvroSchemaPostProcessor.java:49) ~[springwolf-core.jar:na] at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721) ~[na:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:49) ~[springwolf-core.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:33) ~[springwolf-core.jar:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.lambda$removeAvroProperties$0(AvroSchemaPostProcessor.java:49) ~[springwolf-core.jar:na] at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721) ~[na:na] at io.github.springwolf.core.asyncapi.components.postprocessors.AvroSchemaPostProcessor.removeAvroProperties(AvroSchemaPostProcessor.java:49) ~[springwolf-core.jar:na] 2024-11-04T00:28:15.321+03:00 INFO 16064 --- [Springwolf example project - AMQP] [ntContainer#0-2] o.s.a.r.l.SimpleMessageListenerContainer : Waiting for workers to finish. 2024-11-04T00:28:15.321+03:00 INFO 16064 --- [Springwolf example project - AMQP] [ntContainer#0-2] o.s.a.r.l.SimpleMessageListenerContainer : Successfully waited for workers to finish. 2024-11-04T00:28:15.321+03:00 INFO 16064 --- [Springwolf example project - AMQP] [ntContainer#1-2] o.s.a.r.l.SimpleMessageListenerContainer : Waiting for workers to finish. 2024-11-04T00:28:15.321+03:00 INFO 16064 --- [Springwolf example project - AMQP] [ntContainer#1-2] o.s.a.r.l.SimpleMessageListenerContainer : Successfully waited for workers to finish. 2024-11-04T00:28:15.321+03:00 INFO 16064 --- [Springwolf example project - AMQP] [ntContainer#2-2] o.s.a.r.l.SimpleMessageListenerContainer : Waiting for workers to finish. 2024-11-04T00:28:15.321+03:00 INFO 16064 --- [Springwolf example project - AMQP] [ntContainer#2-2] o.s.a.r.l.SimpleMessageListenerContainer : Successfully waited for workers to finish. 2024-11-04T00:28:15.322+03:00 INFO 16064 --- [Springwolf example project - AMQP] [ntContainer#3-2] o.s.a.r.l.SimpleMessageListenerContainer : Waiting for workers to finish. 2024-11-04T00:28:15.322+03:00 INFO 16064 --- [Springwolf example project - AMQP] [ntContainer#3-2] o.s.a.r.l.SimpleMessageListenerContainer : Successfully waited for workers to finish. 2024-11-04T00:28:15.322+03:00 INFO 16064 --- [Springwolf example project - AMQP] [ntContainer#4-2] o.s.a.r.l.SimpleMessageListenerContainer : Waiting for workers to finish. 2024-11-04T00:28:15.322+03:00 INFO 16064 --- [Springwolf example project - AMQP] [ntContainer#4-2] o.s.a.r.l.SimpleMessageListenerContainer : Successfully waited for workers to finish. 2024-11-04T00:28:15.322+03:00 INFO 16064 --- [Springwolf example project - AMQP] [ntContainer#5-2] o.s.a.r.l.SimpleMessageListenerContainer : Waiting for workers to finish. 2024-11-04T00:28:15.322+03:00 INFO 16064 --- [Springwolf example project - AMQP] [ntContainer#5-2] o.s.a.r.l.SimpleMessageListenerContainer : Successfully waited for workers to finish. 2024-11-04T00:28:15.322+03:00 INFO 16064 --- [Springwolf example project - AMQP] [ntContainer#6-2] o.s.a.r.l.SimpleMessageListenerContainer : Waiting for workers to finish. 2024-11-04T00:28:15.322+03:00 INFO 16064 --- [Springwolf example project - AMQP] [ntContainer#6-2] o.s.a.r.l.SimpleMessageListenerContainer : Successfully waited for workers to finish. ```
timonback commented 1 day ago

If you have configured springwolf in init lazy mode, the endpoint must be called first.

It sounds like that you have adapted the example already. Do you mind putting it on a branch and open a PR? That improves chances that we can quickly reproduce it. (Similar to i.e.: https://github.com/springwolf/springwolf-core/pull/764 )

When running gradlew test (ApiSystemTest), the error/exception should appear.


Just using your proto file did not reproduce the error for me, i havent looked into the dependencies nor used both request and response object together.

slava110 commented 19 hours ago

I've created PR #1053. I can also upload to GitHub my own project's source code c:

Just using your proto file did not reproduce the error for me, i havent looked into the dependencies nor used both request and response object together.

Maybe it's a problem specifically with protobuf + RabbitMQ mix?

slava110 commented 17 hours ago

I've used debug mode and UnknownFieldSet from ProtoBuf seems to be the problem? It seems to reference itself in property defaultInstanceForType. As I understand:

  1. removeAvroProperties called for UnkownFieldSet schema
  2. It gets schema properties, finds defaultInstanceForType property, calls removeAvroProperties on it
  3. This property has $ref to UnkownFieldSet so during this removeAvroProperties call execution goes into schema.get$ref() != null condition. Where removeAvroProperties called on referenced class
  4. removeAvroProperties called for UnkownFieldSet schema (referenced class)
  5. Cycle repeats

image image

I might be wrong cause I have no idea what's going on with avro properties and haven't dig into your codebase much. So take it with a grain of salt