'SpringDoc openAPI tool not scanning for APIs in Spring Boot Project

I'm having trouble getting this to work. I've started with a working SpringBoot (v2.2.2) app with a working @RestController. To get springdoc to work I've included the following dependency in my pom:

 <dependency>
  <groupId>org.springdoc</groupId>
  <artifactId>springdoc-openapi-ui</artifactId>
  <version>1.2.28</version>
</dependency>

I then built and started my service. I've then browsed to the api-docs endpoint and I get:

{"openapi":"3.0.1","info":{"title":"OpenAPI definition","version":"v0"},"servers":[{"url":"http://localhost:8081","description":"Generated server url"}],"paths":{},"components":{}}

Am I missing a step? I was assuming at runtime it would scan my code, find the @RestController, find the @RequestMapping methods and generate the api from that.

As a second attempt, I decided to annotate one of my methods with swagger @Operation annotations and still things don't get picked up.

Lastly, I tried specifying the package with my Controller manually using springdoc.packagesToScan and that didn't work either.

This feels like springdoc isn't seeing my Controller.. even though spring does.. it's perfectly active and it works..

Not sure what I'm missing..

here are my project dependencies:

[INFO] +- org.springframework.boot:spring-boot-starter-web:jar:2.2.2.RELEASE:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter:jar:2.2.2.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot:jar:2.2.2.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-autoconfigure:jar:2.2.2.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-starter-logging:jar:2.2.2.RELEASE:compile
[INFO] |  |  |  +- ch.qos.logback:logback-classic:jar:1.2.3:compile
[INFO] |  |  |  |  \- ch.qos.logback:logback-core:jar:1.2.3:compile
[INFO] |  |  |  +- org.apache.logging.log4j:log4j-to-slf4j:jar:2.12.1:compile
[INFO] |  |  |  |  \- org.apache.logging.log4j:log4j-api:jar:2.12.1:compile
[INFO] |  |  |  \- org.slf4j:jul-to-slf4j:jar:1.7.29:compile
[INFO] |  |  +- jakarta.annotation:jakarta.annotation-api:jar:1.3.5:compile
[INFO] |  |  \- org.yaml:snakeyaml:jar:1.25:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter-json:jar:2.2.2.RELEASE:compile
[INFO] |  |  +- com.fasterxml.jackson.core:jackson-databind:jar:2.10.1:compile
[INFO] |  |  |  +- com.fasterxml.jackson.core:jackson-annotations:jar:2.10.1:compile
[INFO] |  |  |  \- com.fasterxml.jackson.core:jackson-core:jar:2.10.1:compile
[INFO] |  |  +- com.fasterxml.jackson.datatype:jackson-datatype-jdk8:jar:2.10.1:compile
[INFO] |  |  +- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:2.10.1:compile
[INFO] |  |  \- com.fasterxml.jackson.module:jackson-module-parameter-names:jar:2.10.1:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter-tomcat:jar:2.2.2.RELEASE:compile
[INFO] |  |  +- org.apache.tomcat.embed:tomcat-embed-core:jar:9.0.29:compile
[INFO] |  |  +- org.apache.tomcat.embed:tomcat-embed-el:jar:9.0.29:compile
[INFO] |  |  \- org.apache.tomcat.embed:tomcat-embed-websocket:jar:9.0.29:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter-validation:jar:2.2.2.RELEASE:compile
[INFO] |  |  +- jakarta.validation:jakarta.validation-api:jar:2.0.1:compile
[INFO] |  |  \- org.hibernate.validator:hibernate-validator:jar:6.0.18.Final:compile
[INFO] |  |     +- org.jboss.logging:jboss-logging:jar:3.4.1.Final:compile
[INFO] |  |     \- com.fasterxml:classmate:jar:1.5.1:compile
[INFO] |  +- org.springframework:spring-web:jar:5.2.2.RELEASE:compile
[INFO] |  |  \- org.springframework:spring-beans:jar:5.2.2.RELEASE:compile
[INFO] |  \- org.springframework:spring-webmvc:jar:5.2.2.RELEASE:compile
[INFO] |     +- org.springframework:spring-aop:jar:5.2.2.RELEASE:compile
[INFO] |     +- org.springframework:spring-context:jar:5.2.2.RELEASE:compile
[INFO] |     \- org.springframework:spring-expression:jar:5.2.2.RELEASE:compile
[INFO] +- com.google.guava:guava:jar:28.1-jre:compile
[INFO] |  +- com.google.guava:failureaccess:jar:1.0.1:compile
[INFO] |  +- com.google.guava:listenablefuture:jar:9999.0-empty-to-avoid-conflict-with-guava:compile
[INFO] |  +- com.google.code.findbugs:jsr305:jar:3.0.2:compile
[INFO] |  +- org.checkerframework:checker-qual:jar:2.8.1:compile
[INFO] |  +- com.google.errorprone:error_prone_annotations:jar:2.3.2:compile
[INFO] |  +- com.google.j2objc:j2objc-annotations:jar:1.3:compile
[INFO] |  \- org.codehaus.mojo:animal-sniffer-annotations:jar:1.18:compile
[INFO] +- org.apache.commons:commons-lang3:jar:3.9:compile
[INFO] +- org.springdoc:springdoc-openapi-ui:jar:1.2.28:compile
[INFO] |  +- org.springdoc:springdoc-openapi-webmvc-core:jar:1.2.28:compile
[INFO] |  |  \- org.springdoc:springdoc-openapi-common:jar:1.2.28:compile
[INFO] |  |     +- io.swagger.core.v3:swagger-models:jar:2.1.1:compile
[INFO] |  |     +- io.swagger.core.v3:swagger-annotations:jar:2.1.1:compile
[INFO] |  |     \- io.swagger.core.v3:swagger-integration:jar:2.1.1:compile
[INFO] |  |        \- io.swagger.core.v3:swagger-core:jar:2.1.1:compile
[INFO] |  |           +- javax.xml.bind:jaxb-api:jar:2.3.1:compile
[INFO] |  |           |  \- javax.activation:javax.activation-api:jar:1.2.0:compile
[INFO] |  |           +- com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:jar:2.10.1:compile
[INFO] |  |           \- javax.validation:validation-api:jar:2.0.1.Final:compile
[INFO] |  +- org.webjars:swagger-ui:jar:3.24.3:compile
[INFO] |  \- org.webjars:webjars-locator:jar:0.38:compile
[INFO] |     \- org.webjars:webjars-locator-core:jar:0.41:compile
[INFO] |        +- io.github.classgraph:classgraph:jar:4.8.44:compile
[INFO] |        \- org.webjars.npm:angular__http:jar:2.4.10:compile
[INFO] +- org.assertj:assertj-core:jar:3.14.0:test
[INFO] \- org.springframework.boot:spring-boot-starter-test:jar:2.2.2.RELEASE:test
[INFO]    +- org.springframework.boot:spring-boot-test:jar:2.2.2.RELEASE:test
[INFO]    +- org.springframework.boot:spring-boot-test-autoconfigure:jar:2.2.2.RELEASE:test
[INFO]    +- com.jayway.jsonpath:json-path:jar:2.4.0:test
[INFO]    |  +- net.minidev:json-smart:jar:2.3:test
[INFO]    |  |  \- net.minidev:accessors-smart:jar:1.2:test
[INFO]    |  |     \- org.ow2.asm:asm:jar:5.0.4:test
[INFO]    |  \- org.slf4j:slf4j-api:jar:1.7.29:compile
[INFO]    +- jakarta.xml.bind:jakarta.xml.bind-api:jar:2.3.2:test
[INFO]    |  \- jakarta.activation:jakarta.activation-api:jar:1.2.1:test
[INFO]    +- org.junit.jupiter:junit-jupiter:jar:5.5.2:test
[INFO]    |  +- org.junit.jupiter:junit-jupiter-api:jar:5.5.2:test
[INFO]    |  |  +- org.opentest4j:opentest4j:jar:1.2.0:test
[INFO]    |  |  \- org.junit.platform:junit-platform-commons:jar:1.5.2:test
[INFO]    |  +- org.junit.jupiter:junit-jupiter-params:jar:5.5.2:test
[INFO]    |  \- org.junit.jupiter:junit-jupiter-engine:jar:5.5.2:test
[INFO]    +- org.junit.vintage:junit-vintage-engine:jar:5.5.2:test
[INFO]    |  +- org.apiguardian:apiguardian-api:jar:1.1.0:test
[INFO]    |  +- org.junit.platform:junit-platform-engine:jar:1.5.2:test
[INFO]    |  \- junit:junit:jar:4.12:test
[INFO]    +- org.mockito:mockito-junit-jupiter:jar:3.1.0:test
[INFO]    +- org.hamcrest:hamcrest:jar:2.1:test
[INFO]    +- org.mockito:mockito-core:jar:3.1.0:test
[INFO]    |  +- net.bytebuddy:byte-buddy:jar:1.10.4:test
[INFO]    |  +- net.bytebuddy:byte-buddy-agent:jar:1.10.4:test
[INFO]    |  \- org.objenesis:objenesis:jar:2.6:test
[INFO]    +- org.skyscreamer:jsonassert:jar:1.5.0:test
[INFO]    |  \- com.vaadin.external.google:android-json:jar:0.0.20131108.vaadin1:test
[INFO]    +- org.springframework:spring-core:jar:5.2.2.RELEASE:compile
[INFO]    |  \- org.springframework:spring-jcl:jar:5.2.2.RELEASE:compile
[INFO]    +- org.springframework:spring-test:jar:5.2.2.RELEASE:test
[INFO]    \- org.xmlunit:xmlunit-core:jar:2.6.3:test

here is the tree of my project.. it's a standard spring boot structure.. The Controller is under the web dir/package

.
├── java
│   └── com
│       └── neodem
│           └── orl
│               ├── collections
│               ├── config
│               ├── engine
│               │   ├── core
│               │   │   ├── actions
│               │   │   └── model
│               │   └── original
│               │       ├── actions
│               │       └── model
│               ├── service
│               └── web
└── resources


Solution 1:[1]

It's because you're using springdoc-openapi-ui, it uses when you want to integrate springdoc-openapi with Swagger UI, so for check the results you should first add and enable Swagger UI then check the swagger link. like: http://localhost:8080/swagger-ui.html.

If you don't want swagger you must use springdoc-openapi-core instead of springdoc-openapi-ui.

In summary

Solution 1

  • Add and Enable Swagger UI
  • Check the Swagger Url ({server-address}:{port}/swagger-ui.html.)

Solution 2

  • Change dependency from springdoc-openapi-ui to springdoc-openapi-core

Your dependency must like below snippet:

<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-core</artifactId>
    <version>1.1.44</version>
</dependency>

Solution 3

List the packages to include in the documentation by config

#Packages to include
springdoc.packagesToScan=com.neodem.orl.web

Also This link might be useful. (Documenting a Spring REST API Using springdoc-openapi)

Solution 2:[2]

I have found the solution in my case, and posted a the springdoc git Issue (https://github.com/springdoc/springdoc-openapi/issues/378). It reads (in part):

when defining a REST Controller, spring allows you to declare @RequestMapping(value = "/init") with no explicit Method and will accept a POST request. However, in your OpenApiResource class you make a call to calculatePath, in there (on line 129) you make a call to the spring RequestMappingInfo.getMethodsCondition() and in my case you get back no results (since the method wasn't explicitly defined in the annotation).. thus no request method => no path calculated.

If I explicitly define the method: @RequestMapping(value = "/init", method = RequestMethod.POST) everything works as expected.

so the solution is to explicitly declare the Method in the @RequestMapping

Solution 3:[3]

Just to add that I had the same issue and solved by replacing @Controller by @RestController.

Solution 4:[4]

It is: Instead of:

@GetMapping(BookConfig.BOOK_ENDPOINT)

You must do:

@RequestMapping(value = BookConfig.BOOK_ENDPOINT, method = RequestMethod.GET)

This was a major pain to discover the root cause. OpenAPI needs to enhance its framework to support Spring's latest annotation version. It has actually been there for quite some time, already. Less typing is the way to go.

Solution 5:[5]

That resolved it for me. It did not recognize @Controller. It found every API after using @RestController instead. Paths for the UI are (assuming port 8080):
http://localhost:8080/swagger-ui/index.html
http://localhost:8080/v3/api-docs
http://localhost:8080/v3/api-docs.yaml

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Vincent Fumo
Solution 3 Gardella Juan
Solution 4 Gabriel Jimenez
Solution 5 procrastinator