avatarClean Code Clean Life

Summarize

Resolving Bean Name Conflicts in OpenAPI-Generated Spring Boot Applications

Introduction:

OpenAPI is a powerful tool for generating APIs quickly and easily. However, when working with multiple YAML files and paths that collide, as in the below case of the `/trade-messages` endpoint, you might encounter some challenges. One such challenge is the naming conflict when OpenAPI generates two classes with the same type, which can lead to a “org.springframework.context.annotation.ConflictingBeanDefinitionException” when running a Spring Boot application. In this blog post, we’ll explore a solution to this problem and how to implement it.

The Dilemma:

You have two YAML files, each defining endpoints under `/trade-messages`. OpenAPI generates two TradeMessageApi classes for these endpoints. Since they are in different folders, it’s not a problem at the file level. However, when you run your Spring Boot application, it throws the below exception

Caused by: org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name for bean class conflicts with existing, non-compatible bean definition of same name and class

The issue is straightforward; both classes have the same type(in my case the bean type is tradeMessageAPI), which causes a conflict.

Manual vs. Generated Beans:

The usual solution for dealing with bean conflicts is to provide a unique name (i.e. wired by name instead of the by default autowired byType )when autowiring the beans manually. Unfortunately, in this case, these classes were generated automatically by openapi-generator-maven-plugin, and changing them manually is impossible.

package a.b.c.d;
@RestController("MyTradeMessageAPI")
public class TradeMessageAPI{
...
}
package c.d.e.f;
@RestController("YourTradeMessageAPI")
public class TradeMessageAPI{
...
}

The Solution:

A solution to this naming conflict is to use the “useTags” configuration option inside the OpenAPI Generator plugin configuration. This will result in the generated classes having different names, thus avoiding the bean naming collision. Let’s walk through the steps to implement this solution:

1. Locate your OpenAPI Generator plugin configuration. You need to find the configuration for the OpenAPI Generator in your project. It’s usually defined in your build.gradle or pom.xml file, depending on whether you’re using Gradle or Maven.

2. Add the “useTags” Configuration Option. In the plugin configuration, find the place where you specify the generator options. You will add the “useTags” option there. Here’s an example:

For Maven, it might look like this:

<configuration>
<generatorName>spring</generatorName>
      <generateApis>true</generateApis>
      <generateApiTests>true</generateApiTests>
      <useTags>true</useTags> <!-- Add this line -->
  </configuration>

3. Regenerate the API Code.

After adding the “useTags” option, you will need to regenerate the API code using the OpenAPI Generator (if you are using maven, then the command is `mvn clean install`). This will create new classes with distinct names for your endpoints.

Conclusion:

Solving naming conflicts in Spring Boot applications generated by OpenAPI can be a straightforward process. By using the “useTags” configuration option, you can ensure that the generated classes have distinct names, preventing bean naming collisions. This approach allows you to continue leveraging the power of OpenAPI while maintaining a clean and functional Spring Boot application.

🔸Thank you for reading 👍.

If you liked this story then click on 👏👏 do follow for more interesting and helpful stories.

If you enjoyed this article, consider trying out the AI service I recommend. It provides the same performance and functions to ChatGPT Plus(GPT-4) but more cost-effective, at just $6/month (Special offer for $1/month). Click here to try ZAI.chat.

Spring Boot
Openapi Specification
Swagger Codegen
Troubleshooting
Spring Training
Recommended from ReadMedium