Skip to content

When the controller inherits a generic class, there is an infinite loop #2271

Closed
@wenqiuhan

Description

@wenqiuhan

(HI,I'm sorry but English is not my native language, so I use Machine translation. If you have any doubts about the problems I described, please feel free to reply me.)

Problem Description

The controller's parent class has a generic type, and the return value of a method is a generic type,
When subclassing inheritance, the real type is provided, but when accessing doc. html, there will be an infinite loop. The specific code is as follows,
I don't know if this is a bug. If not, please tell me how to solve this problem

Dependencies version

spring-boot 3.0.5
springdoc-openapi-starter-webmvc-ui 2.0.4
springdoc-openapi-starter-common 2.0.4

Simplified the code to obtain the following code
// Controller subclass
import com.wenqiuhan.starter.web.controller.SuperController;
import com.wenqiuhan.test.web.entity.SysUser;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/sysUser")
public class SysUserController extends SuperController<SysUser> {

}


// Controller superclass
import com.wenqiuhan.common.web.entity.SuperEntity;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

public abstract class SuperController<T extends SuperEntity<T>> {

    @GetMapping({"page/{current}/{size}", "page"})
    public List<? extends T> findPage(@PathVariable(required = false) Long current,
                                      @PathVariable(required = false) Long size,
                                      @RequestParam(required = false) T params) {
        return new ArrayList<>();
    }
}
Specific error reporting
jakarta.servlet.ServletException: Handler dispatch failed: java.lang.StackOverflowError
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1096) ~[spring-webmvc-6.0.7.jar:6.0.7]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:974) ~[spring-webmvc-6.0.7.jar:6.0.7]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1011) ~[spring-webmvc-6.0.7.jar:6.0.7]
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903) ~[spring-webmvc-6.0.7.jar:6.0.7]
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:527) ~[jakarta.servlet-api-6.0.0.jar:6.0.0]
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.0.7.jar:6.0.7]
	at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:614) ~[jakarta.servlet-api-6.0.0.jar:6.0.0]
	at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74) ~[undertow-servlet-2.3.4.Final.jar:2.3.4.Final]
	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129) ~[undertow-servlet-2.3.4.Final.jar:2.3.4.Final]
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.0.7.jar:6.0.7]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.7.jar:6.0.7]
	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:67) ~[undertow-servlet-2.3.4.Final.jar:2.3.4.Final]
	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.3.4.Final.jar:2.3.4.Final]
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.0.7.jar:6.0.7]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.7.jar:6.0.7]
	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:67) ~[undertow-servlet-2.3.4.Final.jar:2.3.4.Final]
	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.3.4.Final.jar:2.3.4.Final]
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.0.7.jar:6.0.7]
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.7.jar:6.0.7]
	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:67) ~[undertow-servlet-2.3.4.Final.jar:2.3.4.Final]
	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.3.4.Final.jar:2.3.4.Final]
	at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84) ~[undertow-servlet-2.3.4.Final.jar:2.3.4.Final]
	at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) ~[undertow-servlet-2.3.4.Final.jar:2.3.4.Final]
	at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68) ~[undertow-servlet-2.3.4.Final.jar:2.3.4.Final]
	at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) ~[undertow-servlet-2.3.4.Final.jar:2.3.4.Final]
	at io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:68) ~[undertow-servlet-2.3.4.Final.jar:2.3.4.Final]
	at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:117) ~[undertow-servlet-2.3.4.Final.jar:2.3.4.Final]
	at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) ~[undertow-servlet-2.3.4.Final.jar:2.3.4.Final]
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-2.3.4.Final.jar:2.3.4.Final]
	at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) ~[undertow-core-2.3.4.Final.jar:2.3.4.Final]
	at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) ~[undertow-servlet-2.3.4.Final.jar:2.3.4.Final]
	at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60) ~[undertow-core-2.3.4.Final.jar:2.3.4.Final]
	at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77) ~[undertow-servlet-2.3.4.Final.jar:2.3.4.Final]
	at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43) ~[undertow-core-2.3.4.Final.jar:2.3.4.Final]
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-2.3.4.Final.jar:2.3.4.Final]
	at io.undertow.servlet.handlers.SendErrorPageHandler.handleRequest(SendErrorPageHandler.java:52) ~[undertow-servlet-2.3.4.Final.jar:2.3.4.Final]
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-2.3.4.Final.jar:2.3.4.Final]
	at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:276) ~[undertow-servlet-2.3.4.Final.jar:2.3.4.Final]
	at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135) ~[undertow-servlet-2.3.4.Final.jar:2.3.4.Final]
	at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:132) ~[undertow-servlet-2.3.4.Final.jar:2.3.4.Final]
	at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48) ~[undertow-servlet-2.3.4.Final.jar:2.3.4.Final]
	at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43) ~[undertow-servlet-2.3.4.Final.jar:2.3.4.Final]
	at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:256) ~[undertow-servlet-2.3.4.Final.jar:2.3.4.Final]
	at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:101) ~[undertow-servlet-2.3.4.Final.jar:2.3.4.Final]
	at io.undertow.server.Connectors.executeRootHandler(Connectors.java:393) ~[undertow-core-2.3.4.Final.jar:2.3.4.Final]
	at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:859) ~[undertow-core-2.3.4.Final.jar:2.3.4.Final]
	at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18) ~[jboss-threads-3.5.0.Final.jar:3.5.0.Final]
	at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513) ~[jboss-threads-3.5.0.Final.jar:3.5.0.Final]
	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1512) ~[jboss-threads-3.5.0.Final.jar:3.5.0.Final]
	at org.xnio.XnioWorker$WorkerThreadFactory$1$1.run(XnioWorker.java:1282) ~[xnio-api-3.8.8.Final.jar:3.8.8.Final]
	at java.lang.Thread.run(Thread.java:833) ~[?:?]
Caused by: java.lang.StackOverflowError
	at sun.reflect.generics.reflectiveObjects.TypeVariableImpl.hashCode(TypeVariableImpl.java:178) ~[?:?]
	at java.util.Arrays.hashCode(Arrays.java:4499) ~[?:?]
	at sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl.hashCode(ParameterizedTypeImpl.java:209) ~[?:?]
	at org.springframework.util.ObjectUtils.nullSafeHashCode(ObjectUtils.java:436) ~[spring-core-6.0.7.jar:6.0.7]
	at org.springframework.core.ResolvableType.calculateHashCode(ResolvableType.java:932) ~[spring-core-6.0.7.jar:6.0.7]
	at org.springframework.core.ResolvableType.<init>(ResolvableType.java:148) ~[spring-core-6.0.7.jar:6.0.7]
	at org.springframework.core.ResolvableType.forType(ResolvableType.java:1429) ~[spring-core-6.0.7.jar:6.0.7]
	at org.springframework.core.ResolvableType.forType(ResolvableType.java:1398) ~[spring-core-6.0.7.jar:6.0.7]
	at org.springframework.core.ResolvableType.resolveType(ResolvableType.java:850) ~[spring-core-6.0.7.jar:6.0.7]
	at org.springframework.core.ResolvableType.getGenerics(ResolvableType.java:721) ~[spring-core-6.0.7.jar:6.0.7]
	at org.springframework.core.ResolvableType.hasUnresolvableGenerics(ResolvableType.java:547) ~[spring-core-6.0.7.jar:6.0.7]
	at org.springdoc.core.parsers.ReturnTypeParser.resolveType(ReturnTypeParser.java:89) ~[springdoc-openapi-starter-common-2.0.4.jar:2.0.4]
	at org.springdoc.core.parsers.ReturnTypeParser.resolveType(ReturnTypeParser.java:95) ~[springdoc-openapi-starter-common-2.0.4.jar:2.0.4]
	at org.springdoc.core.parsers.ReturnTypeParser.resolveType(ReturnTypeParser.java:95) ~[springdoc-openapi-starter-common-2.0.4.jar:2.0.4]
	at org.springdoc.core.parsers.ReturnTypeParser.resolveType(ReturnTypeParser.java:95) ~[springdoc-openapi-starter-common-2.0.4.jar:2.0.4]
	at org.springdoc.core.parsers.ReturnTypeParser.resolveType(ReturnTypeParser.java:95) ~[springdoc-openapi-starter-common-2.0.4.jar:2.0.4]
	at org.springdoc.core.parsers.ReturnTypeParser.resolveType(ReturnTypeParser.java:95) ~[springdoc-openapi-starter-common-2.0.4.jar:2.0.4]
	at org.springdoc.core.parsers.ReturnTypeParser.resolveType(ReturnTypeParser.java:95) ~[springdoc-openapi-starter-common-2.0.4.jar:2.0.4]
......

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions