Skip to content

Nested type parameters for implementation type cause NullPointerException #2793

@Mobe91

Description

@Mobe91

The following works but is impractical since I need to support multiple response types:

@OpenAPIDefinition
@Path("distances")
public interface DistancesResource {
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    Map<UUID, Map<RouteMetric, Integer>> getDistances();
}

Thus I changed the return type of my resource to Response and used @ApiResponses to designate the possible concrete response types. However, specifying Map<UUID, Map<RouteMetric, Integer>> directly in the annotation is not possible due to the generics involved. Thus I introduced a dummy type for this purpose:

@OpenAPIDefinition
@Path("distances")
public interface DistancesResource {
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @ApiResponses({
            @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = DistancesResponse.class)))
    })
    Response getDistances();

    abstract class DistancesResponse implements Map<UUID, Map<RouteMetric, Integer>> { }
}

However, resolving the model information now fails with the following exception:

09:15:09,946 ERROR [io.undertow.request] (default task-25) UT005023: Exception handling request to /openapi: java.lang.NullPointerException
	at io.swagger.v3.core.jackson.ModelResolver.resolve(ModelResolver.java:356)
	at io.swagger.v3.core.converter.ModelConverterContextImpl.resolve(ModelConverterContextImpl.java:90)
	at io.swagger.v3.core.converter.ModelConverters.readAllAsResolvedSchema(ModelConverters.java:99)
	at io.swagger.v3.core.util.AnnotationsUtils.getSchema(AnnotationsUtils.java:1054)
	at io.swagger.v3.core.util.AnnotationsUtils.getSchema(AnnotationsUtils.java:1039)
	at io.swagger.v3.core.util.AnnotationsUtils.getContent(AnnotationsUtils.java:995)
	at io.swagger.v3.jaxrs2.OperationParser.getApiResponses(OperationParser.java:76)
	at io.swagger.v3.jaxrs2.Reader.parseMethod(Reader.java:899)
	at io.swagger.v3.jaxrs2.Reader.parseMethod(Reader.java:754)
	at io.swagger.v3.jaxrs2.Reader.read(Reader.java:422)
	at io.swagger.v3.jaxrs2.Reader.read(Reader.java:169)
	at io.swagger.v3.jaxrs2.Reader.read(Reader.java:196)
	at io.swagger.v3.oas.integration.GenericOpenApiContext.read(GenericOpenApiContext.java:353)
	at io.swagger.v3.jaxrs2.integration.OpenApiServlet.doGet(OpenApiServlet.java:49)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
	at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)
	at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
	at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
	at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
	at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
	at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
	at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
	at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
	at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
	at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at org.wildfly.extension.undertow.deployment.GlobalRequestControllerHandler.handleRequest(GlobalRequestControllerHandler.java:68)
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292)
	at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81)
	at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138)
	at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135)
	at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
	at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
	at org.wildfly.extension.undertow.security.SecurityContextThreadSetupAction.lambda$create$0(SecurityContextThreadSetupAction.java:105)
	at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
	at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
	at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
	at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
	at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
	at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272)
	at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
	at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104)
	at io.undertow.server.Connectors.executeRootHandler(Connectors.java:326)
	at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:812)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

Workaround

@OpenAPIDefinition
@Path("distances")
public interface DistancesResource {
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @ApiResponses({
            @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = DistancesResponse.class)))
    })
    Response getDistances();

    @JsonIgnoreProperties("empty")
    abstract class DistancesResponse implements Map<UUID, DistancesResponseEntry > { }

    @JsonIgnoreProperties("empty")
    abstract class DistancesResponseEntry implements Map<RouteMetric, Integer> { }
}

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