Search code examples
jakarta-eeswaggerwebsphere-libertyjax-rpc

WebSphere Liberty fails to automatically generate swagger for JAX-RS api


In multiple projects in my company we use WebSphere Liberty Profile with the apiDiscovery-1.0 feature to automatically generate a swagger.json that describes our api. But one specific project is failing.

The log display the following stack trace that I believe is related to the problem (scroll right to see the meat of the message):

[AUDIT   ] CWWKT0016I: Aplicativo da Web disponível (default_host): http://d-00884081.domain.net:14099/mycontext/
[ERROR   ] CWWKE0701E: [com.ibm.ws.rest.api.discovery.APIProviderAggregator(316)] The setApiProvider method has thrown an exception Bundle:com.ibm.ws.rest.api.discovery(id=120) java.util.ServiceConfigurationError: io.swagger.jaxrs.ext.SwaggerExtension: Provider io.swagger.jersey.SwaggerJersey2Jaxrs not a subtype
    at java.util.ServiceLoader.fail(ServiceLoader.java:239)
    at java.util.ServiceLoader.access$300(ServiceLoader.java:185)
    at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:376)
    at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)
    at java.util.ServiceLoader$1.next(ServiceLoader.java:480)
    at io.swagger.jaxrs.ext.SwaggerExtensions.<clinit>(SwaggerExtensions.java:31)
    at [internal classes]

If everything worked fine, I expected to be able to access the swagger file at one of these URLs:

I don't really understand the error message and what I must do to fix it.

Maybe it is something about using Jersey as a JAX-RS implementation. Here are the dependencies in the project pom.xml:

        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-core</artifactId>
            <version>1.5.16</version>
        </dependency>

        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-jersey2-jaxrs</artifactId>
            <version>1.5.16</version>
        </dependency>

I tried to change the jersey2 dependency to

        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-jaxrs</artifactId>
            <version>1.5.13</version>
            <scope>compile</scope>
        </dependency>

But now the code does not compile, because the class javax.ws.rs.core.Response now doesn't have the symbol readEntity. It looks like it is using an old api that just has the symbol getEntity. I can't really change to code to the old api because it is used at o lot places.

I use an Application class approach to activate the JAX-RS. Here is a simplified version of it:

@ApplicationPath("/api")
@SwaggerDefinition(
        info=@Info(
            version="1.4",
            title="API REST",
            description="a description",
        ),
        schemes=SwaggerDefinition.Scheme.HTTP,  
        consumes={MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON},
        produces={MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON},
)
public class JaxRsActivator extends Application {
    @Inject private Logger log;

    public JaxRsActivator() {
    }
}

How should I modify my configuration to correctly generate the swagger.json file?


Solution

  • The error you are hitting looks like some sort of classloading conflict between the version of Swagger that Liberty provides and the version of Swagger that you are packaging inside of your application.

    The apiDiscovery-1.0 feature will provide Swagger core libs, and the io.swagger.annotations package to your application, so it should not be necessary to also package these Swagger jars in your app. Try changing those dependencies to provided scope.

    Side note: I see you are including swagger-jersey2-jaxrs for some reason. Is this because your app is using Jersey as a third-party JAX-RS implementation? If you enable one of the jaxrs-2.X features, Liberty will automatically provide Apache CXF as the JAX-RS runtime (you do not need to package anything in your app).