Skip to content

Unable to use Springdoc without Spring Boot dependency #1199

@KupchinskiyVasiliy

Description

@KupchinskiyVasiliy

Describe the bug
I get java.lang.NoClassDefFoundError when try to use Springdoc with excluded org.springframework.boot:spring-boot dependency.

Stacktrace
javax.servlet.ServletException: org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.NoClassDefFoundError: org/springframework/boot/web/servlet/error/ErrorController
    at org.eclipse.jetty.server.handler.HandlerCollection.handle (HandlerCollection.java:162)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle (HandlerWrapper.java:127)
	...
    at java.lang.Thread.run (Thread.java:834)
Caused by: org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.NoClassDefFoundError: org/springframework/boot/web/servlet/error/ErrorController
    at org.springframework.web.servlet.DispatcherServlet.doDispatch (DispatcherServlet.java:1055)
    at org.springframework.web.servlet.DispatcherServlet.doService (DispatcherServlet.java:943)
    at org.springframework.web.servlet.FrameworkServlet.processRequest (FrameworkServlet.java:1006)
    at org.springframework.web.servlet.FrameworkServlet.doGet (FrameworkServlet.java:898)
    at javax.servlet.http.HttpServlet.service (HttpServlet.java:687)
	...
    at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run (QueuedThreadPool.java:938)
    at java.lang.Thread.run (Thread.java:834)
Caused by: java.lang.NoClassDefFoundError: org/springframework/boot/web/servlet/error/ErrorController
    at java.lang.ClassLoader.defineClass1 (Native Method)
    at java.lang.ClassLoader.defineClass (ClassLoader.java:1017)
    at java.security.SecureClassLoader.defineClass (SecureClassLoader.java:174)
    at java.net.URLClassLoader.defineClass (URLClassLoader.java:550)
    at java.net.URLClassLoader$1.run (URLClassLoader.java:458)
    at java.net.URLClassLoader$1.run (URLClassLoader.java:452)
    at java.security.AccessController.doPrivileged (Native Method)
    at java.net.URLClassLoader.findClass (URLClassLoader.java:451)
    at org.eclipse.jetty.webapp.WebAppClassLoader.foundClass (WebAppClassLoader.java:649)
    at org.eclipse.jetty.webapp.WebAppClassLoader.loadAsResource (WebAppClassLoader.java:622)
    at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass (WebAppClassLoader.java:534)
    at java.lang.ClassLoader.loadClass (ClassLoader.java:522)
    at java.lang.ClassLoader.defineClass1 (Native Method)
    at java.lang.ClassLoader.defineClass (ClassLoader.java:1017)
    at java.security.SecureClassLoader.defineClass (SecureClassLoader.java:174)
    at java.net.URLClassLoader.defineClass (URLClassLoader.java:550)
    at java.net.URLClassLoader$1.run (URLClassLoader.java:458)
    at java.net.URLClassLoader$1.run (URLClassLoader.java:452)
    at java.security.AccessController.doPrivileged (Native Method)
    at java.net.URLClassLoader.findClass (URLClassLoader.java:451)
    at org.eclipse.jetty.webapp.WebAppClassLoader.foundClass (WebAppClassLoader.java:649)
    at org.eclipse.jetty.webapp.WebAppClassLoader.loadAsResource (WebAppClassLoader.java:622)
    at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass (WebAppClassLoader.java:534)
    at java.lang.ClassLoader.loadClass (ClassLoader.java:522)
    at java.lang.Class.forName0 (Native Method)
    at java.lang.Class.forName (Class.java:315)
    at org.springdoc.core.OpenAPIService.initializeHiddenRestController (OpenAPIService.java:231)
    at org.springdoc.core.OpenAPIService.build (OpenAPIService.java:220)
    at org.springdoc.api.AbstractOpenApiResource.getOpenApi (AbstractOpenApiResource.java:272)
    at org.springdoc.webmvc.api.OpenApiResource.openapiJson (OpenApiResource.java:176)
    at org.springdoc.webmvc.api.OpenApiWebMvcResource.openapiJson (OpenApiWebMvcResource.java:116)
    at org.springdoc.webmvc.api.MultipleOpenApiWebMvcResource.openapiJson (MultipleOpenApiWebMvcResource.java:93)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    ...
    at java.lang.Thread.run (Thread.java:834)
Caused by: java.lang.ClassNotFoundException: org.springframework.boot.web.servlet.error.ErrorController
    at org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass (SelfFirstStrategy.java:50)
    at org.codehaus.plexus.classworlds.realm.ClassRealm.unsynchronizedLoadClass (ClassRealm.java:271)
    at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass (ClassRealm.java:247)
    at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass (ClassRealm.java:239)
    at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass (WebAppClassLoader.java:543)
    at java.lang.ClassLoader.loadClass (ClassLoader.java:522)
    at java.lang.ClassLoader.defineClass1 (Native Method)
    at java.lang.ClassLoader.defineClass (ClassLoader.java:1017)
    at java.security.SecureClassLoader.defineClass (SecureClassLoader.java:174)
    at java.net.URLClassLoader.defineClass (URLClassLoader.java:550)
    at java.net.URLClassLoader$1.run (URLClassLoader.java:458)
    at java.net.URLClassLoader$1.run (URLClassLoader.java:452)
    at java.security.AccessController.doPrivileged (Native Method)
    at java.net.URLClassLoader.findClass (URLClassLoader.java:451)
    at org.eclipse.jetty.webapp.WebAppClassLoader.foundClass (WebAppClassLoader.java:649)
    at org.eclipse.jetty.webapp.WebAppClassLoader.loadAsResource (WebAppClassLoader.java:622)
    at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass (WebAppClassLoader.java:534)
    at java.lang.ClassLoader.loadClass (ClassLoader.java:522)
    at java.lang.ClassLoader.defineClass1 (Native Method)
    at java.lang.ClassLoader.defineClass (ClassLoader.java:1017)
    at java.security.SecureClassLoader.defineClass (SecureClassLoader.java:174)
    at java.net.URLClassLoader.defineClass (URLClassLoader.java:550)
    at java.net.URLClassLoader$1.run (URLClassLoader.java:458)
    at java.net.URLClassLoader$1.run (URLClassLoader.java:452)
    at java.security.AccessController.doPrivileged (Native Method)
    at java.net.URLClassLoader.findClass (URLClassLoader.java:451)
    at org.eclipse.jetty.webapp.WebAppClassLoader.foundClass (WebAppClassLoader.java:649)
    at org.eclipse.jetty.webapp.WebAppClassLoader.loadAsResource (WebAppClassLoader.java:622)
    at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass (WebAppClassLoader.java:534)
    at java.lang.ClassLoader.loadClass (ClassLoader.java:522)
    at java.lang.Class.forName0 (Native Method)
    at java.lang.Class.forName (Class.java:315)
    at org.springdoc.core.OpenAPIService.initializeHiddenRestController (OpenAPIService.java:231)
    at org.springdoc.core.OpenAPIService.build (OpenAPIService.java:220)
    at org.springdoc.api.AbstractOpenApiResource.getOpenApi (AbstractOpenApiResource.java:272)
    at org.springdoc.webmvc.api.OpenApiResource.openapiJson (OpenApiResource.java:176)
    at org.springdoc.webmvc.api.OpenApiWebMvcResource.openapiJson (OpenApiWebMvcResource.java:116)
    at org.springdoc.webmvc.api.MultipleOpenApiWebMvcResource.openapiJson (MultipleOpenApiWebMvcResource.java:93)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:566)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke (InvocableHandlerMethod.java:190)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest (InvocableHandlerMethod.java:138)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle (ServletInvocableHandlerMethod.java:105)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod (RequestMappingHandlerAdapter.java:878)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal (RequestMappingHandlerAdapter.java:792)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle (AbstractHandlerMethodAdapter.java:87)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch (DispatcherServlet.java:1040)
    at org.springframework.web.servlet.DispatcherServlet.doService (DispatcherServlet.java:943)
    at org.springframework.web.servlet.FrameworkServlet.processRequest (FrameworkServlet.java:1006)
    at org.springframework.web.servlet.FrameworkServlet.doGet (FrameworkServlet.java:898)
    at javax.servlet.http.HttpServlet.service (HttpServlet.java:687)
    at org.springframework.web.servlet.FrameworkServlet.service (FrameworkServlet.java:883)
    at javax.servlet.http.HttpServlet.service (HttpServlet.java:790)
    at org.eclipse.jetty.servlet.ServletHolder$NotAsyncServlet.service (ServletHolder.java:1411)
    at org.eclipse.jetty.servlet.ServletHolder.handle (ServletHolder.java:763)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter (ServletHandler.java:1631)
    at org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter.doFilter (WebSocketUpgradeFilter.java:226)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter (ServletHandler.java:1618)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter (FilterChainProxy.java:327)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke (FilterSecurityInterceptor.java:115)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter (FilterSecurityInterceptor.java:81)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter (FilterChainProxy.java:336)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter (ExceptionTranslationFilter.java:119)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter (ExceptionTranslationFilter.java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter (FilterChainProxy.java:336)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter (AnonymousAuthenticationFilter.java:105)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter (FilterChainProxy.java:336)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter (SecurityContextHolderAwareRequestFilter.java:149)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter (FilterChainProxy.java:336)
    at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal (BasicAuthenticationFilter.java:178)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:119)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter (FilterChainProxy.java:336)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter (AbstractAuthenticationProcessingFilter.java:218)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter (AbstractAuthenticationProcessingFilter.java:212)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter (FilterChainProxy.java:336)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal (RequestContextFilter.java:100)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:119)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter (FilterChainProxy.java:336)
    at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter (HeaderWriterFilter.java:90)
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal (HeaderWriterFilter.java:75)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:119)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter (FilterChainProxy.java:336)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal (WebAsyncManagerIntegrationFilter.java:55)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:119)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter (FilterChainProxy.java:336)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter (SecurityContextPersistenceFilter.java:110)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter (SecurityContextPersistenceFilter.java:80)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter (FilterChainProxy.java:336)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal (FilterChainProxy.java:211)
    at org.springframework.security.web.FilterChainProxy.doFilter (FilterChainProxy.java:183)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate (DelegatingFilterProxy.java:358)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter (DelegatingFilterProxy.java:271)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter (ServletHandler.java:1618)
    at org.springframework.web.multipart.support.MultipartFilter.doFilterInternal (MultipartFilter.java:125)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:119)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter (ServletHandler.java:1618)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal (CharacterEncodingFilter.java:201)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:119)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter (ServletHandler.java:1618)
    at ch.qos.logback.classic.helpers.MDCInsertingServletFilter.doFilter (MDCInsertingServletFilter.java:49)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter (ServletHandler.java:1618)
    at com.onevizion.web.filter.RedirectToHttpsFilter.doFilter (RedirectToHttpsFilter.java:50)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate (DelegatingFilterProxy.java:358)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter (DelegatingFilterProxy.java:271)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter (ServletHandler.java:1610)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle (ServletHandler.java:549)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle (ScopedHandler.java:143)
    at org.eclipse.jetty.security.SecurityHandler.handle (SecurityHandler.java:602)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle (HandlerWrapper.java:127)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle (ScopedHandler.java:235)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle (SessionHandler.java:1610)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle (ScopedHandler.java:233)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle (ContextHandler.java:1369)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope (ScopedHandler.java:188)
    at org.eclipse.jetty.servlet.ServletHandler.doScope (ServletHandler.java:489)
    at org.eclipse.jetty.server.session.SessionHandler.doScope (SessionHandler.java:1580)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope (ScopedHandler.java:186)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope (ContextHandler.java:1284)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle (ScopedHandler.java:141)
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle (ContextHandlerCollection.java:234)
    at org.eclipse.jetty.server.handler.HandlerCollection.handle (HandlerCollection.java:146)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle (HandlerWrapper.java:127)
    at org.eclipse.jetty.server.Server.handle (Server.java:501)
    at org.eclipse.jetty.server.HttpChannel.lambda$handle$1 (HttpChannel.java:383)
    at org.eclipse.jetty.server.HttpChannel.dispatch (HttpChannel.java:556)
    at org.eclipse.jetty.server.HttpChannel.handle (HttpChannel.java:375)
    at org.eclipse.jetty.server.HttpConnection.onFillable (HttpConnection.java:272)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded (AbstractConnection.java:311)
    at org.eclipse.jetty.io.FillInterest.fillable (FillInterest.java:103)
    at org.eclipse.jetty.io.ChannelEndPoint$1.run (ChannelEndPoint.java:104)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob (QueuedThreadPool.java:806)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run (QueuedThreadPool.java:938)
    at java.lang.Thread.run (Thread.java:834)

Looks like URLClassLoader throws NoClassDefFoundError instead of ClassNotFoundException. Can you also handle NoClassDefFoundError in OpenAPIService.java?

https://github.com/springdoc/springdoc-openapi/blob/master/springdoc-openapi-common/src/main/java/org/springdoc/core/OpenAPIService.java#L233
https://github.com/springdoc/springdoc-openapi/blob/master/springdoc-openapi-common/src/main/java/org/springdoc/core/OpenAPIService.java#L238

To Reproduce
Steps to reproduce the behavior:

  • What version of spring-boot you are using?
    Nothing

  • What modules and versions of springdoc-openapi are you using?
    springdoc-openapi-webmvc-core:1.5.9
    springdoc-openapi-common:1.5.9

  • What is the actual and the expected result using OpenAPI Description (yml or json)?
    json

  • Provide with a sample code (HelloController) or Test that reproduces the problem

pom.xml:

<dependencies>
        <dependency>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-webmvc-core</artifactId>
            <version>1.5.9</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
            <version>2.5.0</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
</dependencies>

SpringdocConf.java:

import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import io.swagger.v3.oas.models.security.SecurityScheme;
import org.springdoc.core.GroupedOpenApi;
import org.springdoc.core.SpringDocConfigProperties;
import org.springdoc.core.SpringDocConfiguration;
import org.springdoc.core.SpringDocHints;
import org.springdoc.webmvc.core.MultipleOpenApiSupportConfiguration;
import org.springdoc.webmvc.core.SpringDocWebMvcConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@Import({SpringDocConfiguration.class,
        SpringDocConfigProperties.class,
        SpringDocHints.class,
        SpringDocWebMvcConfiguration.class,
        MultipleOpenApiSupportConfiguration.class})
public class SpringdocConf {

    @Bean
    public GroupedOpenApi actuatorApi() {
        return GroupedOpenApi.builder().group("Actuator")
                             .pathsToMatch("/v3/**")
                             .build();
    }

    @Bean
    public OpenAPI customOpenAPI() {
        return new OpenAPI()
                .components(new Components().addSecuritySchemes("basicScheme",
                        new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("basic")))
                .info(new Info().title("Petstore API").version("228").description(
                        "This is a sample server Petstore server.  You can find out more about     Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/).      For this sample, you can use the api key `special-key` to test the authorization     filters.")
                                .termsOfService("http://swagger.io/terms/")
                                .license(new License().name("Apache 2.0").url("http://springdoc.org")));
    }

}

Expected behavior

  • I want to get generated openapi json

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions