The CXF OpenApiFeature allows you to generate OpenAPI v3.0 documents from JAX-RS service endpoints with a simple configuration. This feature can be configured programmatically in Java or using Spring or Blueprint beans.



The cxf-rt-rs-service-description-openapi-v3 is only available in 3.2.x and above due to Java 8 baseline. For older releases, as well as for the users of older Swagger specifications 1.x/2.x, there is a dedicated converter provided: org.apache.cxf.jaxrs.swagger.openapi.SwaggerToOpenApiConversionFilter.


The following optional parameters can be configured in OpenApiFeature. Note that although there are some similarities with Swagger specifications 1.x/2.x, OpenAPI v3.0 is a significant revamp of the specification (in a good sense of it).

NameDescriptionDefault value (if applicable)Sample value (if applicable)

the OpenAPI configuration location


scan known OpenAPI configuration location (classpath or filesystem), which are:

propertiesLocationthe properties file location/ /
securityDefinitionsa list of security definitions*null

["basicAuth" -> new SecurityScheme().type(Type.HTTP))]

customizerthe customizer class instancenullnew OpenApiCustomizer()
swaggerUiMavenGroupAndArtifactthe Maven artifacts to pinpoint SwaggerUInull"org.webjars.swagger-ui'
swaggerUiVersionthe version of SwaggerUInull"3.13.0"
supportSwaggerUiturns on/off SwaggerUI supportnull (== true)true
filterClassa security filter**null"com.example.filter.SampleFilter"
resourceClassesa list of resource classes which must be scanned**null[""]
resourcePackagesa list of package names where resources must be scanned**null[""]
ignoredRoutesexcludes specific paths when scanning all resources (see scanAllResources)**null["/api/test"]
prettyPrintwhen generating openapi.json, pretty-print the JSON document**truetrue
runAsFilterruns the feature as a filterfalsefalse
scanScan all JAX-RS resources automaticallytruetrue
readAllResourcesRead all operations also with no @Operation** truetrue
termsOfServiceUrlthe terms of service URL*nullnull
licenseUrlthe license URL*null""
licensethe license*null"Apache 2.0 License"
contactUrlthe contact link*nullnull
contactEmailthe contact email*null""
contactNamethe contact name*nullnull
descriptionthe description*null"The Sample REST Application with OpenAPI integration"
titlethe title*null"Sample REST Application"
versionthe version*null"1.0.0"
swaggerUiConfigSwagger UI configurationnullnew SwaggerUiConfig().url("/openapi.json")
useContextBasedConfigIf set, the unique Context Id is going to be generated for each OpenApiContext instance (see please Using Multiple Server Endpoints). Also, you very likely may want to set scan property to false.falsefalse
scannerClassthe name of the JAX-RS API scanner class, used to scope the application, resource packages, resource classes and classpath scanning, please refer to Resource Scanning sectionnullio.swagger.v3.jaxrs2.integration.JaxrsApplicationScanner

* - the properties are defined in the OpenAPI class

 ** - the properties are defined in the SwaggerConfiguration class

Configuring from Code

import org.apache.cxf.jaxrs.openapi.OpenApiFeature;


final OpenApiFeature feature = new OpenApiFeature();
feature.setLicense("Apache 2.0 License");
feature.setSecurityDefinitions(Collections.singletonMap("basicAuth",new SecurityScheme().type(Type.HTTP)));

Configuring from Spring

<beans xmlns=""
       xmlns:xsi="" xmlns:cxf=""
    <!-- JAXRS providers -->
    <bean id="jsonProvider" class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider" />
    <!-- Application resources -->
    <bean id="sampleResource" class="demo.jaxrs.openapi.server.Sample" />
    <!-- CXF OpenApiFeature -->  
    <bean id="openApiFeature" class="org.apache.cxf.jaxrs.openapi.OpenApiFeature">
        <!-- customize some of the properties -->

    <jaxrs:server id="sampleServer" address="/swaggerSample">
            <ref bean="sampleResource" />
            <ref bean="jsonProvider" />
            <ref bean="openApiFeature" />

Configuring in Blueprint

In case of Apache Karaf, the OpenAPI v3.0 integration is available as cxf-rs-description-openapi-v3 feature.

feature:install cxf-rs-description-openapi-v3
<blueprint xmlns=""
    <!-- JAXRS providers -->
    <bean id="jsonProvider" class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider" />
    <!-- Application resources -->
    <bean id="sampleResource" class="demo.jaxrs.openapi.server.Sample" />
    <!-- CXF OpenApiFeature -->  
    <bean id="openApiFeature" class="org.apache.cxf.jaxrs.openapi.OpenApiFeature">
        <!-- customize some of the properties -->

    <jaxrs:server id="sampleServer" address="/swaggerSample">
            <ref component-id="sampleResource" />
            <ref component-id="jsonProvider" />
            <ref component-id="openApiFeature" />

Configuring in CXFNonSpringJaxrsServlet


        <display-name>CXF Servlet</display-name>

Configuring from Property files

It is possible to supply the configuration from the property files. The default location for a properties file is "/". OpenApiFeature will pick it up if it is available, and the location can be overridden with a 'propertiesLocation' property.  Additionally, the complete OpenAPI configuration could be supplied from the property file (usually openapi-configuration.json or openapi-configuration.yml), controlled by 'configLocation' property. By default, OpenApiFeature scans for known OpenAPI configuration locations and loads them if available (the behavior could be switched off by setting scanKnownConfigLocations to false). Please take into account that there is a certain level of the overlap between both.

Note that the properties, if available, do not override the properties which may have been set as suggested above from the code or Spring/Blueprint contexts or web.xml. Instead they complement and serve as the default configuration properties: for example, if some properties have been set from the code then the values for the same properties found in the properties file will not be used.

Spring Boot Auto Configuration

Please consult samples/jax_rs/spring_boot and on how to create OpenApiFeature as a @Bean or/and samples/jax_rs/spring_boot_scan on how to auto-enable it. By default, the OpenApiCustomizer instance will be preconfigured for  OpenApiFeature since the base path is often unknown to CXF.

Enabling Swagger UI

Adding a Swagger UI Maven dependency is all what is needed to start accessing Swagger documents with the help of Swagger UI.


For example, let's assume a JAX-RS endpoint is published at 'http://host:port/context/services/'.

Open the browser and go to 'http://host:port/context/services/api-docs/?url=/openapi.json' which will return a Swagger UI page.

CXF Services page will also link to Swagger UI. Go to 'http://host:port/context/services/' and follow a Swagger link which will return a Swagger UI page.

See samples/jax_rs/description_openapi_v3 as an example.

To deactivate automatic Swagger UI integration please set 'supportSwaggerUi' property to "false".

Enabling Swagger UI in OSGi container (Karaf)

Since org.webjars/swagger-ui is just a package with resources, it won't be referenced in OSGi manifest as the required imports. Therefore, to make use of Swagger UI in the OSGi deployments, the org.webjars/swagger-ui should be installed manually, for example:

karaf@root()> install mvn:org.webjars/swagger-ui/3.23.8

The dedicated Activator will take care of discovering the presence of the org.webjars/swagger-ui bundle and configuring OpenApiFeature.

Configuring Swagger UI (3.2.7+)

The OpenApiFeature  has a way to pre-configure certain  Swagger UI parameters ( through SwaggerUiConfig. The way it is implemented is by passing those parameters as a query string so the Swagger UI could adjust itself.

Apache CXF prior to 3.4.6 / 3.5.1 passed Swagger UI configuration (url, ...) as query parameters. Starting from Swagger UI 4.1.3, most of query parameters are not accepted anymore (due to security concerns), and Apache CXF employes different strategy and tries to replace the URL dynamically (inside HTML) when serving Swagger UI's front web page. This behaviour could be turned off by setting queryConfigEnabled  property of the SwaggerUiConfig to true (the default value is false and URLs are replaced dynamically). Please notice that in this case the customized Swagger UI bundle is required since queryConfigEnabled  property could only be set by altering the distribution (

The typical initialization for server-side dynamical URL replacement  looks like this:

new SwaggerUiConfig()

In other words:

  • when queryConfigEnabled  is set to false, Apache CXF will dynamically replace the URL in SwaggerUI, in this respect the value won't be taken from the query string but from url property of the SwaggerUI configuration, this is a default behavior
  • when queryConfigEnabled is set to true, Apache CXF will do nothing and just forward query parameters to SwaggerUI (hoping it will somehow take care of it), in general that implies custom SwaggerUI distribution has to be used

Using Multiple Server Endpoints (3.3.0+)

Quite often there are more than one JAXRSServerFactoryBean configured within same Apache CXF application, for example, under "/admin" and "/public" endpoints. The older Swagger/OpenAPI v2.0 integrations used such basePath to disambiguate multiple API documentation contexts, but since OpenAPI v3.0 Specification does not explicitly include the concept of basePath anymore, this approach is not working. Luckily, starting from 2.0.6 release, Swagger OpenAPI v3 implementation properly supports Context Id. To activate it from OpenApiFeature, it is enough to set useContextBasedConfig property to true (very likely you would also want to set scan to false).

final OpenApiFeature feature = new OpenApiFeature();

With that, each OpenApiFeature will generate unique Context Id and won't see any classes / packages beyond its own configuration.


CXF's distribution contains the following samples.

  • No labels


  1. Hi,

    Do we have an example that works for tomcat based Application. I used the above example and modified my web.xml to point my Application, but while accessing my service it does not show any endpoint. Do we have a full example somewhere that works on tomcat and not just on Springboot or Jetty ? 

    Thank you ! 

    1. Hi Irfan,

      We don't have such an example right but the documentation should have covered this particular deployment as well, working on that, the update should be available shortly. Thank you!

      1. That would be great. What seems to be missing in the documentation is configuring a complete web.xml and then if we need to create our own servlet for invoking the REST Service. It is a very small piece but very important for people like me who uses tomcat than Springboot/jetty based servers. 

        1. Hi Irfan,

          Please take a look on this sample It is pure WAR / web.xml based, no Spring or any other CDI framework. One important detail though, because servlet mapping could be set to any context path, the sample project uses 'openapi-configuration.json' file (src/main/resources) to supply this missing information in the 'servers' section (so Swagger UI would properly detect the URLs to call).

          Also, if you deploy at non-root context path in Tomcat, please make the appropriate corrections in the URL to browse your specification, f.e.: http://<host>:<port>/<context path>/app/api-docs?url=/<context path>/app/openapi.json , that should be it (smile)

          Thank you.

  2. This is exactly what I am looking for. Thank you very much for doing it. Will let you know how it goes (smile)

  3. Your example worked perfectly fine, thank you very much again !  

    So, if I am running a Spring Application in CXF based tomcat Web Application, what would you recommend for configuring OpenAPI. For example, I see ApiOriginFilter is redundant if we have Spring Security. Also, how can I configure openapi-configuration.json differently for Spring CXF based Web Applications.

    1. Awesome, glad to hear that! There are other choices, beside using `openapi-configuration.json`. You may prefer to use `OpenApiCustomizer` in case you could have easy ways to inject features into your application. The good example is this sample project. The customizer approach is preferred/easier in case of programmatic configuration, it could be also used with `web.xml` but needs a bit more initialization logic.

  4. Cool. Also, is there a multiple classes for which we want to generate swagger file, is the only option adding all the class names separated by "," or can I add a package name ?

    1. You could specify packages through `resourcePackages` property or classes through `resourceClasses` property, whatever is better option for you.

  5. Makes sense. Also, is there a way I can add a basepath ? I do not see that option anywhere. The reason for asking this is that, this example works fine if I deploy it as ROOT. But for non-ROOT WebApp, I get the swagger output but I cannot execute it as the openapi.json|yaml always considers the WebApp as "ROOT". I am sure there would be a way because in swagger1 there was something like swagger.uri.basepath which could be set in the code or in the web.xml. 

    1. Right, so the OpenAPI v3 is significantly different from Swagger (though serving the same purpose). The basepath is not available anymore, instead there is a concept of 'servers'. You can find it in the 'openapi-configuration.json' for one of the samples from above (where the URL is set to not full URL but context path only, like '/app'). The `OpenApiCustomizer` does the same with 'dynamicBasePath' property. If set to 'true', it does similar thing automatically by extracting the context path from the URL and injecting the entry into `servers` component. So these 2 ways should help you out with non-ROOT WebApp or similar cases, like in the sample we talked about before, which uses `OpenApiCustomizer` to deal with this issue.

  6. Aaah, I see. Let me pitch out my thoughts so that I understand it correctly.

    So lets say if I have my webApp as "demoSrv", then can I set that in openapi-configuration.json URL as below    

    "servers": [
    "url": "/demoSrv/app",
    "description": "Test WebApp"

    If this does not work then if I add a OpenAPICustomer class as below it should automatically set the URL in openapi.json|yaml with "WebApp" name. Am I right ? 

    package demo.jaxrs.openapi.server;

    import org.apache.cxf.jaxrs.openapi.OpenApiCustomizer;
    import org.apache.cxf.jaxrs.openapi.OpenApiFeature;

    public class Customizer {

    public OpenApiFeature createOpenApiFeature() {
    OpenApiFeature openApiFeature = new OpenApiFeature();
    OpenApiCustomizer customizer = new OpenApiCustomizer();
    openApiFeature.setTitle("Spring Boot CXF REST Application");
    openApiFeature.setContactName("The Apache CXF team");
    openApiFeature.setDescription("This sample project demonstrates how to use CXF JAX-RS services"
    + " with Spring Boot. This demo has two JAX-RS class resources being"
    + " deployed in a single JAX-RS endpoint.");
    return openApiFeature;

    Also, what would be the init param that I would use to execute this class at the beginning for initialization ?

    1. You just need one of the those two approaches: openapi-configuration.json or OpenApiCustomizer. For init-param initializing the feature property to a class instance inside web.xml is not supported (afaik), so you may have only openapi-configuration.json as an option.

    2. Or, if you still think about using OpenApiCustomizer in case of web.xml / war, you could go with custom feature:

      public class CustomOpenApiFeature extends OpenApiFeature {
          public CustomOpenApiFeature() {
              OpenApiCustomizer customizer = new OpenApiCustomizer();

      And than use it in web.xml instead of org.apache.cxf.jaxrs.openapi.OpenApiFeature:

  7. Okay, it looks like there is a bug somewhere. It always consider the WebApp path as blank which is "ROOT". Generation of swagger file is fine based on the WebApp, but it is missing the context of WebApp while executing it inside OpenAPI. If I deploy your example into my own webapp(lets say 'demoSrv') and execute it in OpenAPI UI then it misses the webapp name.

  8. Andriy,

    I just tried both the approaches(with .json and with CustomApiFeature) and they both show me the same behavior. 'setDynamicBasePath' property to true/false does not show any difference to me.

    1. Sorry, just to make sure we are using the same versions, are you on 3.2.5-SNAPSHOT (or 3.2.4)?

  9. I am using 3.2.4 as mentioned in the wiki Setup. Was it not a stable version ? 

    1. That's right, 3.2.4 is a stable version. Examples are based of 3.2.5-SNAPSHOT which has slight improvements over 3.2.4. Could you please modify your feature init param value to explicitly have `configLocation` property set, like that (if you use custom feature, it will also work the same way).



      1. This works perfectly fine. Now I can insert my WebApp name and I can execute my API's correctly from OpenAPI UI.

        Thank you very much Andriy, you have been very patient (smile)

        So, is this a bug that it is not picking the config file correctly ?

        1. Awesome, thank you Irfan. There was an improvement in 3.2.5 (not released yet, in SNAPSHOT) to simplify the discovery of of the well-known OpenAPI configuration locations automatically. For 3.2.4 it still requires property to be set explicitly.

          1. Cool, so why isn't the same thing picked up in CustomOpenAPIFeature class ?

            1. Technical obstacles, we are working on that, might be available soon (but not now), sorry.

              1. Thats fine, just wanted to know. Is there a way I can get to know when this issue will be fixed or a Jira bug-id I can track.

                Works very well, glad to work with you. Got to learn a lot on this stuff. Looks like I am the first one to work on this API (smile)

                Thank you very much ! I will look forward for the latest release.

                1. Awesome, good luck! Regarding your question, you may be interested in CXF-7694 - Getting issue details... STATUS and comments. There is no open issue right now, but you are welcome to submit one. Thank you!

  10. So my maven project complains that it could not find 3.2.5 snapshot and I did not see that it is publicly available.

    Missing artifact org.apache.cxf:cxf-rt-rs-service-description-openapi-v3:jar:3.2.5-SNAPSHOT

  11. FYI, I took the latest repository from here and it is missing the openapi-v3.jar.

    1. Interesting, I see a lot of JARs missed there, we'll take a look, thanks for heads up!

  12. Thank you, Andriy!

    The documentation helped me to set up OpenAPI3 with Spring Boot 2 + Apache CXF!

    There is one thing I am still trying to figure out with OpenAPI3, restricting swagger definitions per CXF endpoint (based on the path)! I would like to define two CXF endpoints ("/admin" & "/public") & on each of them, only the specific swagger definitions should be visible! can you follow?

    Is this supported? Looking forward to your answer.

    1. Hi Bharanidharan Viswanathan,

      Thank you for the feedback. Yes, very good question, so for Swagger 1.3.x / 1.5.x we contributed a patch to support that (if I am remember correctly). Since OpenApi is mostly a rewrite / new code, we would need to come up with another patch (very likely). Would you mind please to create a JIRA ticket ( to track it? Thank you.

      1. Thank you Andriy Redko for the quick response.

        Here is the ticket CXF-7749 - OpenApi 3.0: Enable restriction of swagger definitions per CXF endpoint (based on the path) Open please feel free to update the ticket as you see it necessary. Looking forward to the resolution.

        1. Andriy Redko do you any futher information on the above ticket ? is there already a plan for its availability ? please let me know.

          1. Bharanidharan Viswanathan the ticket is planned for sure but the work has not started yet, we'll try to wrap it up till next release but it may not be done in CXF only but may require changes in Swagger as well. You may watch the ticket to get notified. Thanks!

  13. Hi Andriy,

    Hope you are doing good ! Wanted to check if you are aware of dates for public availability of 3.2.5 version, If yes can you please share the details.

    Thanks for your help !

    1. Hi Irfan,

      Getting there (smile) You could follow dev mailing list (, the recent discussions are happening here ( Thanks!

      Best Regards,

          Andriy Redko

  14. Hi Andriy,

    Hope you are doing good, got more questions (smile)

    I was using io.swagger.v3.annotations to write my annoations for OpenAPI, but I could not write any class level annotations. All my operations go under "default". Do we have to specify something to make it show as categories for each class ?  The example that you shared also uses "default", I do not see anyway to create class level annotation. It would be great if you can provide me one.

    1. Please ignore it. I was using not using the right annotation.

  15. Hi Andriy,

    I got few questions with swagger-core, not sure if this is the right place to ask. Let me know if I have to post it somewhere else

    1. How would we enable swagger-ui to always not expand the tags when accessing the swagger-ui. Can we configure it in openapi-configuration.json/yaml ? 
    2. Is there a way that we can define examples for Requests as JsonObjects instead of just String ?
    3. Lastly, I am having trouble configuring a Attachment as a Request parameter. Though I configure it multipart type it shows JsonObject for that Request object. Is there a right way of doing it ? 

    Thank you !

    1. Hi Irfan,

      The best way to ask the question is to drop an email at: (smile)

      1. CXF and `openapi-configuration.json/yaml` do not impact Swagger UI behavior anyhow. Some work to pass configuration parameters to SwaggerUI is scheduled under CXF-7826 - Getting issue details... STATUS , but not sure if this particular feature is supported.
      2. It is possible in specification ( but Java annotations are the constraint here (only constants could be used)
      3. This one I am not sure, could be an issue in Swagger UI or Swagger Core/JAX-RS. You could check what is returned as raw specification  (openapi.yaml/json) and than look how Swagger UI interprets it.


      1. Thank you Andriy. I will post the questions to the group going forward.

  16. Andriy Redko Thanks for providing detailed instructions. Found 2 issues though which are not matching with the latest RELEASE version 3.3.1-

    1. CXF 3.2.4 doesn't have property useContextBasedConfig but mentioned in properties table (so maven dependency should have 3.3.1 version instead of 3.2.4).
    2. 'http://host:port/context/services/api-docs/?url=/openapi.json' didn't work for me i had to remove extra slash and it should be something like this- 'http://host:port/context/services/api-docs?url=/openapi.json'
    1. Thanks for the feedback, Rajesh Vyas ,  regarding your points:

      1) That is correct, the useContextBasedConfig property is mentioned in this section Using Multiple Server Endpoints (3.3.0+) which assumes 3.3.x branch

      2) This looks like an issue (minor but still), would you please open a JIRA ticket for it (

      Thank you.

      1. Andriy Redko I was referring to Setup section and it should point to 3.3.x at least to make sure useContextBasedConfig is present as 3.2.4 is missing useContextBasedConfig.

        and for URL 'http://host:port/context/services/api-docs/?url=/openapi.json' i thought it's just documentation issue and need to just update documentation by removing extra slash like this 'http://host:port/context/services/api-docs?url=/openapi.json'?

        Also curious if have a link to this confluence as i guess this is the most upto date documentation.

  17. Hi, I'm using the latest version of CXF in RELEASE 3.3.2 and an implementation of Swagger OpenAPI. In my CXF Services page I realized that the Swagger link has disappeared compared to the Swagger 2 implementation. Is this a bug? Or an option to add? Thanks for your help. Chewb

    1. Hi, it seems like related to CXF-8046 - Getting issue details... STATUS , it is fixed in the 3.3.3 (not released yet). Thank you.

      1. Thank you very much Andriy. Do you know the frequency of releases? The last date of May. Have a good day

        1. You are welcome, I don't have an exact date but I believe the release is expected to be cut in a few weeks. Thank you.