Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception when configuring AsyncApiDocket with Producer and Consumers with the same topic name #136

Closed
AhmedNSidd opened this issue Jan 24, 2023 · 11 comments
Labels
bug Something isn't working waiting for feedback Waiting for user feedback/response

Comments

@AhmedNSidd
Copy link

Describe the bug
An exception occurs if you try to document both a Kafka Consumer and Producer with the same topic name in the AsyncApiDocket configuration bean

Dependencies and versions used

  • Java 8
  • Spring boot 2.7.6
  • springwolf-kafka maven version 0.10.0
  • springwolf-ui maven version 0.6.0

Code example
Configuring using AsyncApiDocket with simple configurations and a producer and a consumer with the same topic name should replicate the error.

@Bean
    public AsyncApiDocket asyncApiDocket() {
        Info info = Info.builder()
                .version("1.0.0")
                .title("Springwolf example project - Kafka")
                .build();

        KafkaProducerData producerData = KafkaProducerData.kafkaProducerDataBuilder()
                .topicName("test")
                .payloadType(String.class)
                .headers(AsyncHeaders.NOT_USED)
                .build();

        KafkaConsumerData consumerData = KafkaConsumerData.kafkaConsumerDataBuilder()
                .topicName("test")
                .payloadType(String.class)
                .build();

        return AsyncApiDocket.builder()
                .basePackage("com.example.demo")
                .info(info)
                .server("kafka", Server.builder().protocol("kafka").url(BOOTSTRAP_SERVERS).build())
                .producer(producerData)
                .consumer(consumerData)
                .build();
    }

Stack trace and error logs

2023-01-24 09:11:21.148  INFO 27900 --- [           main] c.a.springwolf.SpringwolfApplication     : Starting SpringwolfApplication using Java 1.8.0_202 on USLPBF9X2T3 with PID 27900 (C:\Users\ahsiddiqui\Workspace\springwolf-sandbox\springwolf\target\classes started by ahsiddiqui in C:\Users\ahsiddiqui\Workspace\springwolf-sandbox\spr
ingwolf)
2023-01-24 09:11:21.151  INFO 27900 --- [           main] c.a.springwolf.SpringwolfApplication     : No active profile set, falling back to 1 default profile: "default"
2023-01-24 09:11:23.946  INFO 27900 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2023-01-24 09:11:23.956  INFO 27900 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2023-01-24 09:11:23.957  INFO 27900 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.69]
2023-01-24 09:11:24.146  INFO 27900 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2023-01-24 09:11:24.146  INFO 27900 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2953 ms
2023-01-24 09:11:24.289  WARN 27900 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'defaultAsyncApiService' defined in URL [jar:file:/C:/Use
rs/ahsiddiqui/.m2/repository/io/github/springwolf/springwolf-core/0.9.0/springwolf-core-0.9.0.jar!/io/github/stavshamir/springwolf/asyncapi/DefaultAsyncApiService.class]: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean wi
th name 'defaultChannelsService': Invocation of init method failed; nested exception is java.lang.ClassCastException: io.github.stavshamir.springwolf.asyncapi.types.channel.operation.message.Message cannot be cast to java.lang.Comparable
2023-01-24 09:11:24.293  INFO 27900 --- [           main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
2023-01-24 09:11:24.304  INFO 27900 --- [           main] ConditionEvaluationReportLoggingListener :

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2023-01-24 09:11:24.334 ERROR 27900 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'defaultAsyncApiService' defined in URL [jar:file:/C:/Users/ahsiddiqui/.m2/repository/io/github/springwolf/springwolf-core/0.9.0/springwolf-core-0.9.0.jar!/io/github/stavshamir/springwolf/asyncapi/DefaultAsyncApiService.class]: Unsatisfied 
dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'defaultChannelsService': Invocation of init method failed; nested exception is java.lang.ClassCastException: io.github.stavshamir.springwolf.asyncapi.types.channel.operation.
message.Message cannot be cast to java.lang.Comparable
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800) ~[spring-beans-5.3.24.jar:5.3.24]
        at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:229) ~[spring-beans-5.3.24.jar:5.3.24]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1372) ~[spring-beans-5.3.24.jar:5.3.24]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1222) ~[spring-beans-5.3.24.jar:5.3.24]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) ~[spring-beans-5.3.24.jar:5.3.24]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.24.jar:5.3.24]
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.24.jar:5.3.24]
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.24.jar:5.3.24]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.24.jar:5.3.24]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.24.jar:5.3.24]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:955) ~[spring-beans-5.3.24.jar:5.3.24]
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[spring-context-5.3.24.jar:5.3.24]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.24.jar:5.3.24]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) ~[spring-boot-2.7.6.jar:2.7.6]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:731) [spring-boot-2.7.6.jar:2.7.6]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) [spring-boot-2.7.6.jar:2.7.6]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) [spring-boot-2.7.6.jar:2.7.6]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303) [spring-boot-2.7.6.jar:2.7.6]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292) [spring-boot-2.7.6.jar:2.7.6]
        at com.ahmedspocs.springwolf.SpringwolfApplication.main(SpringwolfApplication.java:10) [classes/:na]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'defaultChannelsService': Invocation of init method failed; nested exception is java.lang.ClassCastException: io.github.stavshamir.springwolf.asyncapi.types.channel.operation.message.Message cannot be cast to java.lang.Comparable
        at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:160) ~[spring-beans-5.3.24.jar:5.3.24]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:440) ~[spring-beans-5.3.24.jar:5.3.24]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1796) ~[spring-beans-5.3.24.jar:5.3.24]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620) ~[spring-beans-5.3.24.jar:5.3.24]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.24.jar:5.3.24]
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.24.jar:5.3.24]
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.24.jar:5.3.24]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.24.jar:5.3.24]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.24.jar:5.3.24]
        at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.3.24.jar:5.3.24]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1391) ~[spring-beans-5.3.24.jar:5.3.24]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1311) ~[spring-beans-5.3.24.jar:5.3.24]
        at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887) ~[spring-beans-5.3.24.jar:5.3.24]
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ~[spring-beans-5.3.24.jar:5.3.24]
        ... 19 common frames omitted
Caused by: java.lang.ClassCastException: io.github.stavshamir.springwolf.asyncapi.types.channel.operation.message.Message cannot be cast to java.lang.Comparable
        at java.util.TreeMap.compare(TreeMap.java:1294) ~[na:1.8.0_202]
        at java.util.TreeMap.put(TreeMap.java:538) ~[na:1.8.0_202]
        at java.util.TreeSet.add(TreeSet.java:255) ~[na:1.8.0_202]
        at java.util.AbstractCollection.addAll(AbstractCollection.java:344) ~[na:1.8.0_202]
        at java.util.TreeSet.addAll(TreeSet.java:312) ~[na:1.8.0_202]
        at io.github.stavshamir.springwolf.asyncapi.scanners.channels.ChannelMerger.mergeOperation(ChannelMerger.java:47) ~[springwolf-core-0.9.0.jar:na]
        at io.github.stavshamir.springwolf.asyncapi.scanners.channels.ChannelMerger.merge(ChannelMerger.java:37) ~[springwolf-core-0.9.0.jar:na]
        at io.github.stavshamir.springwolf.asyncapi.DefaultChannelsService.findChannels(DefaultChannelsService.java:37) ~[springwolf-core-0.9.0.jar:na]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_202]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_202]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_202]
        at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_202]
        at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:389) ~[spring-beans-5.3.24.jar:5.3.24]
        at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:333) ~[spring-beans-5.3.24.jar:5.3.24]
        at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:157) ~[spring-beans-5.3.24.jar:5.3.24]
        ... 32 common frames omitted

@AhmedNSidd AhmedNSidd added the bug Something isn't working label Jan 24, 2023
@sam0r040
Copy link
Collaborator

I think the Problem is the TreeSet that is used to merge the messages of multiple operations. TreeSet requires all elements to implement Comparable if no Comparator is given:

Constructs a new, empty tree set, sorted according to the natural ordering of its elements. All elements inserted into the set must implement the Comparable interface.

From https://docs.oracle.com/javase/7/docs/api/java/util/TreeSet.html#TreeSet()

Unfortunately TreeSet does not enforce implementing the interface and Message does not implement comparable.

@timonback
Copy link
Member

I just came across the same issue and resolved it in #137 Checks are still running at this point...

However, I am not sure how to continue with the (message) sorting. @sam0r040 suggested to only do the sorting when items are returned to the ui.
Or, sorting could be done in general in the ui, however checking with the asyncapi.json in the integration tests can become more annoying.

Maybe let the objectMapper do the sorting for us? mapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);

@timonback
Copy link
Member

Fix is released with springwolf-kafka:0.10.3 (including springwolf-core fix)
@AhmedNSidd Are you able to verify this?

@AhmedNSidd
Copy link
Author

AhmedNSidd commented Feb 18, 2023

Fix is released with springwolf-kafka:0.10.3 (including springwolf-core fix) @AhmedNSidd Are you able to verify this?

@timonback

When I try and use springwolf-kafka:0.10.3 and update my pom.xml and use mvn compile, I get the following error. Thoughts?

[ERROR] Failed to execute goal on project springwolf: Could not resolve dependencies for project com.ahmedspocs:springwolf:jar:0.0.1-SNAPSHOT: The following artifacts could not be resolved: io.github.springwolf:springwolf-kafka:jar:0.10.3, io.github.springwolf:springwolf-core:jar:0.9.3: Could not find artifact io.github.springwolf:springwolf-kafka:jar:0.10.3 in central (https://repo.maven.apache.org/maven2) -> [Help 1]

@timonback
Copy link
Member

Good question, havent seen this error before.
The artifact is there at maven: https://repo.maven.apache.org/maven2/io/github/springwolf/springwolf-kafka/ and I also have been using it in another project.

@AhmedNSidd
Copy link
Author

AhmedNSidd commented Mar 8, 2023

@timonback I'm a maven newbie, but I think I've managed to somewhat circle what the issue is, I'll need your knowledge to connect the dots. Upon checking the debug output when I do mvn compile, it tells me that it wasn't able to find io.github.springwolf:springwolf-kafka:jar:0.10.3 in https://repo.maven.apache.org/maven2.

I went to go check and found that springwolf-kafka folder in maven for the 0.10.3 version has no springwolf-kafka-0.10.3.jar file in it, instead it has a .jar file with the plain classifier. This is what is causing the bug when I'm trying to download the dependency from maven.

Again, a newbie here, but perhaps the solution will is to fix the release by adding a simple .jar file without the classifier?

for your reference, this is the highlight of my pom.xml:

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.kafka</groupId>
			<artifactId>spring-kafka</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.kafka</groupId>
			<artifactId>spring-kafka-test</artifactId>
			<scope>test</scope>
		</dependency>
		<!-- Provides the documentation API -->
		<dependency>
			<groupId>io.github.springwolf</groupId>
			<artifactId>springwolf-kafka</artifactId>
			<version>0.10.3</version>
<!--			<classifier>plain</classifier>-->
		</dependency>
		<!-- Provides the UI - optional (recommended) -->
		<dependency>
			<groupId>io.github.springwolf</groupId>
			<artifactId>springwolf-ui</artifactId>
			<version>0.6.0</version>
		</dependency>
	</dependencies>```

@timonback
Copy link
Member

Thank you for the detective work here!

When looking at the maven artifact, there was an (unexpected) change of artifact naming, namely the plain addition to the jar's filename, from 0.10.2 to 0.10.3

I assume it is related to the spring update in springwolf. Possible fix in springwolf is mentioned in https://stackoverflow.com/questions/67663728/spring-boot-2-5-0-generates-plain-jar-file-can-i-remove-it#67752182 but I'll have to come back to it.

timonback added a commit to timonback/springwolf-core that referenced this issue Mar 9, 2023
Regression of the spring boot update released in springwolf 0.10.3

Current artifact name: springwolf-kafka-0.10.3-plain.jar
Should be (previous behaviour): springwolf-kafka-0.10.3.jar

Relates to: springwolf#136
timonback added a commit that referenced this issue Mar 12, 2023
Regression of the spring boot update released in springwolf 0.10.3

Current artifact name: springwolf-kafka-0.10.3-plain.jar
Should be (previous behaviour): springwolf-kafka-0.10.3.jar

Relates to: #136
@timonback
Copy link
Member

With the fix in #152, this is resolved. At least, the latest SNAPSHOT build does not contain the -plain postfix anymore.

Are you able to verify it with maven using version 0.10.3-SNAPSHOT and without the classifier attribute?
The maven snapshot url is mentioned here: https://github.com/springwolf/springwolf-core#sonatype-snapshots

Maven Snapshot Repo: https://s01.oss.sonatype.org/content/repositories/snapshots/io/github/springwolf/springwolf-kafka/0.10.3-SNAPSHOT/

@timonback timonback added the waiting for feedback Waiting for user feedback/response label Mar 12, 2023
@AhmedNSidd
Copy link
Author

@timonback I'm getting the following error when trying to use KafkaConsumerData

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.10.1:compile (default-compile) on project demo: Compilation failure
[ERROR] /mnt/c/Users/ahsiddiqui/Workspace/sandbox/springwolf/demo/src/main/java/com/example/demo/AsyncApiConflguration.java:[5,54] cannot access io.github.stavshamir.springwolf.asyncapi.types.KafkaConsumerData
[ERROR]   bad class file: /home/ahsiddiqui/.m2/repository/io/github/springwolf/springwolf-kafka/0.10.3-SNAPSHOT/springwolf-kafka-0.10.3-SNAPSHOT.jar(io/github/stavshamir/springwolf/asyncapi/types/KafkaConsumerData.class)
[ERROR]     class file has wrong version 61.0, should be 52.0
[ERROR]     Please remove or make sure it appears in the correct subdirectory of the classpath.

@timonback
Copy link
Member

timonback commented Mar 15, 2023

Hi @AhmedNSidd,
The spring boot 3 upgrade was merged in master yesterday, requiring java 17. Based on the message

class file has wrong version 61.0, should be 52.0

I assume that you are running an older java version.
When the next springwolf version is released, we put this info in the release notes.

Since you get this message, the previous issue is resolved, right?

@AhmedNSidd
Copy link
Author

AhmedNSidd commented Mar 15, 2023

@timonback Yup, issue is resolved. I'm not getting the error anymore, and the UI looks majestic. Feel free to close the issue now.

Thanks for your help.

timonback added a commit that referenced this issue Mar 8, 2024
Regression of the spring boot update released in springwolf 0.10.3

Current artifact name: springwolf-kafka-0.10.3-plain.jar
Should be (previous behaviour): springwolf-kafka-0.10.3.jar

Relates to: #136

(cherry picked from commit f5c69ef)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working waiting for feedback Waiting for user feedback/response
Projects
None yet
Development

No branches or pull requests

3 participants