Hi Jean,
I guess you figured one issue, swagger.json -> openapi.json, but to be honest
we have never
tested or envisioned the application that would use OpenAPI 2.0 (Swagger) and
OpenAPI 3.0 at
the same time, I am afraid this is just not supported. You may get things back
on track when
going with OpenAPI 3.0 for all services.
Thank you.
Best Regards,
Andriy Redko
> Hi Andriy,
> I am trying to trace the difference in handling with another application
> where I’ve got only one CXF service endpoint that uses swagger v3 openapi
> annotations.
> There I see that when handling the Swagger page request (
> http://l-p53-008:8082/idb-fe/services/api-docs?url=openapi.json) the
> JAXRSInInterceptor is calling:
> *JAXRSUtils.**getRootResources*(Message message)
> It contains 4 entries:
> - (twice) InkomOndernemingApiserviceImpl -> my service endpoint
> - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource
> - org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService
> On the application described below with the service ‘oidcsim’ when calling
> the swagger page request
> (l-p53-008:8081/op/services/oidcsim/api-docs?url=openapi.json) the result
> of the getRootResources doesn’t contain the ClassResourceInfo ‘
> SwaggerUiService’. It only contains 3 entries:
> - (twice) OidcProviderApiServiceImpl (my service endpoint)
> - io.swagger.v3.jaxrs2.integration.resources.OpenApiResource
> The SwaggerUiService is the one that is configured to handle the ‘api-docs’
> path-request. Since it is missing the request is tried to match with the
> other two resources but fails, hence ‘NOT FOUND’ exception.
> I can’t trace back where these rootResources are set and why the
> SwaggerUiService’ isn’t listed.
> J.P.
> *From:* Jean Pierre URKENS <[email protected]>
> *Sent:* maandag 10 juli 2023 13:43
> *To:* 'Andriy Redko' <[email protected]>
> *Subject:* RE: How to setup multiple JAXRS server endpoints
> Andriy,
> I am trying to switch from Swagger v2 to OpenApi v3 annotations basically
> because my starting point is an OpenApi v3.0.7 yaml file description and
> OpenAPI seems to be the way forward.
> For applications where I have only one CXF JAX-RS endpoint exposed I had no
> problems converting. However as soon as there are multiple endpoints I run
> into troubles.
> So, to recall, I've an application exposing 3 JAX-RS endpoints that where
> previously annotated with swagger v2 annotations (i.e. package
> io.swagger.annotations.*) which I migrated to
> swagger v3 annotations (package io.swagger.v3.oas.annotations.*). In
> accordance I altered my CXF JAX-RS endpoint configuration from (only
> showing relevant parts, see attachment for full setup):
> <!-- CXF Swagger2Feature -->
> <bean id="SwaggerUiConfigOidcApi"
> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">
> <property name="queryConfigEnabled"
> <property name="url"
> value="/op/services/oidcsim/swagger.yaml"/>
> </bean>
> <bean id="Swagger2FeatureOidcApi"
> class="org.apache.cxf.jaxrs.swagger.Swagger2Feature">
> <property name="basePath"
> value="/op/services/oidcsim"/>
> <property name="usePathBasedConfig"
> <property name="resourcePackage"
> value="be.dvtm.aeo.op.oidc"/>
> <property name="supportSwaggerUi"
> <property name="swaggerUiConfig"
> ref="SwaggerUiConfigOidcApi"/>
> </bean>
> <jaxrs:server id="OidcProviderApiServer"
> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">
> ....
> <jaxrs:features>
> <ref
> bean="Swagger2FeatureOidcApi" />
> </jaxrs:features>
> ...
> </jaxrs:server>
> TO:
> <!-- CXF OpenAPIFeature -->
> <bean id="OidcSwaggerUiConfig"
> class="org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">
> <property name="queryConfigEnabled"
> <property name="url" value="openapi.json"/>
> </bean>
> <bean id="OidcOpenApiFeature"
> class="org.apache.cxf.jaxrs.openapi.OpenApiFeature">
> <property name="supportSwaggerUi"
> <property name="swaggerUiConfig"
> ref="OidcSwaggerUiConfig"/>
> <property name="swaggerUiVersion"
> <property name="scan" value="false"/>
> <property name="useContextBasedConfig"
> <property name="resourcePackages"
> value="be.dvtm.aeo.op.oidc"/>
> </bean>
> <jaxrs:server id="OidcProviderApiServer"
> basePackages="be.dvtm.aeo.op.oidc" address="/oidcsim">
> ....
> <jaxrs:features>
> <ref bean="OidcOpenApiFeature"
> </jaxrs:features>
> ...
> </jaxrs:server>
> Now when starting my application and navigating to the root part "
> http://localhost:localPort/op/services" I get an overview of all my
> endpoints:
> Now there are 3 RESTful service endpoints setup:
> 1. ‘oidcsim’ which I switched to swagger v3 annotations
> 2. ‘openapi’ currently still swagger v2 annotations
> 3. ‘sdx’ currently still swagger v2 annotations
> all endpoints work except for the ‘swagger endpoint address for the oidcsim
> endpoint:
> http://l-p53-008:8081/op/services/oidcsim/api-docs?url=/op/services/oidcsim/swagger.json
> So the *WADL* and *OpenAPI* endpoint work but not the *Swagger* endpoint of
> the oidcsim resource. I am getting an error (the value of the ‘url’ query
> parameter isn’t relevant):
> “WebApplicationException has been caught, status: 404,
> message: HTTP 404 Not Found”
> When I try (without the ‘/oidcsim’ context):
> http://l-p53-008:8081/op/services/api-docs I get:
> “No service was found.”
> So the endpoint http://l-p53-008:8081/op/services/oidcsim/api-docs doesn’t
> exist, where as the endpoint http://l-p53-008:8081/op/services/api-docs does
> exist but no service description is found?
> Of course my intention is to get working, as previously with the swagger v2
> setup for which I then specifically added the *Swagger2Feature* config
> parameters:
> <property name="basePath"
> value="/op/services/oidcsim"/>
> <property name="usePathBasedConfig"
> But I don’t find the according configuration options for the
> *OpenApiFeature* class or whether I should configure this in another way.
> Any suggestions on this?
> Regards,
> J.P.
> -----Original Message-----
> From: Andriy Redko <[email protected]>
> Sent: donderdag 25 mei 2023 2:27
> To: Jean Pierre URKENS <[email protected]>; [email protected]
> Subject: Re: How to setup multiple JAXRS server endpoints
> Hi Jean,
> You may run into Swagger JAX-RS scanner limitations, as far as I can tell -
> it checks class annotations for SwaggerDefinition, does not traverse the
> hierarchy [1].
> [1]
> https://github.com/swagger-api/swagger-core/blob/1.5/modules/swagger-jaxrs/src/main/java/io/swagger/jaxrs/Reader.java#L194
> Best Regards,
> Andriy Redko
>> RE: How to setup multiple JAXRS server endpoints
>> Still one question );
>> The generated swagger file doesn’t take into account the
>> @SwaggerDefintion on my interface classes?
>> As a test I looked at
>> *https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma
>> in/release/samples/jax_rs/description_swagger2_web**
>> and** modified** sample2*
>> <https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/ma
>> in/release/samples/jax_rs/description_swagger2_web
>> and modified sample2> as follows:
>> @Path("/sample2")
>> @Api(value = "/sample2",authorizations=
>> {@Authorization(value="bearer")},description = "Sample2
> (modified) JAX-RS
>> service with Swagger documentation")
>> @SwaggerDefinition(
>> info = @Info(
>> description = "Sample2 server",
>> version="1.0",
>> title = "Test2",
>> contact = @Contact(name = "J.P. Urkens",email = "
>> *[email protected]* <
> [email protected]>
>> ")),
>> securityDefinition =
>> @SecurityDefinition(apiKeyAuthDefinitions=
> *{@ApiKeyAuthDefinition(key="bearer",in=ApiKeyLocation.HEADER,name="Authorization",description="Use*
>> <{@ApiKeyAuthDefinition(key=> the format 'Bearer
>> <accessToken>'")})
>> )
>> public class Sample2 {...}
>> This correctly generates the ‘securityDefintions’ in the swagger file.
>> If include the same @SwaggerDefinition and the authorizations on
>> the @Api annotation as above in my interface classes then the
>> generated swagger file doesn’t contain the ‘securityDefintions’ ?
>> Any idea what I might be missing?
>> Regards,
>> J.P.
>> -----Original Message-----
>> From: Jean Pierre URKENS <[email protected]>
>> Sent: dinsdag 23 mei 2023 12:52
>> To: 'Andriy Redko' <[email protected]>; '[email protected]' <
>> Subject: RE: How to setup multiple JAXRS server endpoints
>> Hi Andriy,
>> I added the parameter usePathBasedConfig=true to the
>> Swagger2Feature bean declarations but still it does generate an
>> empty swagger.yaml for interfaces KmopResources and
>> KmopDienstverlener although I noticed that for these interfaces the
>> @Path() annotation was commented out (as I included it in the
>> server declaration). After providing an empty @Path("") declaration on
> the API interface classes everything worked.
>> Thanks for the support.
>> -----Original Message-----
>> From: Andriy Redko <[email protected]>
>> Sent: dinsdag 23 mei 2023 3:42
>> To: Jean Pierre URKENS <[email protected]>;
>> [email protected]
>> Subject: Re: How to setup multiple JAXRS server endpoints
>> Hi Jean,
>> The main problem to configure Swagger property in your particular
>> case is that the server address is not "known" or "introspectable" for
> Swagger.
>> Intuitively, it has to be set manually using basePath to the,
>> essentially, the server address
>> part:
>> - /op/services/accounts
>> - /op/services/resources
>> - /op/services/dienstverlener
>> You could read more about other Swagger properties you have asked here:
>> https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Inte
>> gration-and-Configuration#configuration-properties
>> You definitely need to set usePathBasedConfig to "true" otherwise
>> you will see the same Swagger specs for all servers. We have a
>> sample here which uses 2 jaxrs:server
>> instances:
>> https://github.com/apache/cxf/tree/3.6.x-fixes/distribution/src/mai
>> n/release/samples/jax_rs/description_swagger2_web
>> Regarding SwaggerUI, I think the value for each of those should be
>> set to,
>> respectively:
>> - /op/services/accounts/swagger.yaml
>> - /op/services/resources/swagger.yaml
>> - /op/services/dienstverlener/swagger.yaml
>> I believe this is matching your settings already, except the
>> usePathBasedConfig part. The example referred above could be
>> helpful, my apologies if I missed something, there are quite a lot
>> of questions :-) The fact that the generated Swagger specification
>> is empty is unexpected - it should not happen when JAX-RS resources
> are properly configured.
>> Thank you.
>> Best Regards,
>> Andriy Redko
>>> RE: How to setup multiple JAXRS server endpoints
>>> Hi Andriy,
>>> I am not quite understanding how to correctly configure the
>> Swagger2Feature.
>>> Referring to the attached cxf-endpoints configuration I (as a
>>> test)
>>> created
>>> 3 JAXRS server instances:
>>> 1. A* KmopApiServer* server for the*
>>> be.dvtm.aeo.op.sodexo.api.KmopApiService* interface, serving
>>> requests for URI path:
>>> * <protocol>**//<host:<port>/op/services/accounts*
>>> ‘op’ = root path of the web application
>>> ‘services’ = servlet path of the CXF-servlet
>>> The address of the server is set to ‘/accounts’ and the
>>> @Path(…)
>>> annotation on the interface class was cleared.
>>> 2. A* Kmop**Resources**ApiServer* server for the*
> be.dvtm.aeo.op.*
>>> *openapi.**api.Kmop**Recources**ApiService* interface, serving
>>> requests for URI path:
>>> * <protocol>**//<host:<port>/op/services/**resources*
>>> The address of the server is set to ‘/resources’ and the @Path(…)
>>> annotation on the interface class was cleared.
>>> 3. A* Kmop**Dienstverlener**Server* server for the*
>> be.dvtm.aeo.op.*
>>> *openapi**.api.Kmop**Dienstverlener**Service* interface, serving
>>> requests for URI path:
>>> * <protocol>**//<host:<port>/op/services/**dienstverlener*
>>> The address of the server is set to ‘/dienstverlener’ and the
>>> @Path(…) annotation on the interface class was cleared.
>>> For each of these server instances I’ve set the Swagger2Feature
>>> with configuration as indicated in the attached cxf-endpoints.xml.
>>> With regard to the configurations for the Swagger2Feature I’ve the
>>> following questions:
>>> a) Referring to *
> https://cxf.apache.org/docs/swagger2feature.html*
>>> <https://cxf.apache.org/docs/swagger2feature.html> could you
>>> clarify on the following configuration parameters:
>>> *i. ** basePath* – Is this the path to the CXFServlet context (‘
>>> /op/services’) or to the JAX-RS server instance (e.g.
>>> ‘/op/services/accounts’) or still something else? Is it used to
>>> resolve service classes or is it just for documentation in the
>>> swagger
>> file?
>>> *ii. ** resourcePackage* – the description mentions ‘package names’
>>> while the default mentions ‘service classes’? Service 2 and 3
>>> above
>>> are within the same package (generated from the same yaml
>>> specification that included both interfaces).
>>> *iii. ** ig**noreRoutes* – is this taken into account when
>>> scanAllResources=false?
>>> *iv. ** swaggerUiConfig* – What is the correct ‘url’ parameter
> value
>>> (cf. question ‘a’)?
>>> b) What would be the correct URL to generate a swagger.yaml file
>> for
>>> each of the above interfaces? Initially I called:
>>> *i. **
>> <protocol>**//<host:<port>/op/services/accounts**/swagger.yaml*
>>> *ii. **
>> <protocol>**//<host:<port>/op/services/**resources/swagger.yaml*
>>> *iii. ** <protocol>**//<host:<port>/op/services/**dienstver*
>>> *lener/swagger.yaml*
>>> All three requests delivered the same yaml specification,
>>> namely
>> the one
>>> for interface* KmopApiServer*?
>>> c) I tried to debug the processing of the requests under ‘b)’ and
>> this
>>> is done by the class JAXRSInterceptor#processRequest where the
>>> MessageImpl object for request “ii.” looks like the one attached.
>>> It finds 3 resource
>>> classes:
>>> be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl
>>> org.apache.cxf.jaxrs.swagger.Swagger2ApiListingResource
>>> org.apache.cxf.jaxrs.swagger.ui.SwaggerUiService
>>> è It matches the request to resource*
>> Swagger2ApiListingResource* with
>>> UriInfo={type=[yaml], FINAL_MATCH_GROUP=[/]}} and calling its*
>>> process(…)* method.
>>> è Here it seems to go wrong. It generates a
> SwaggerContextService
>>> having basePath=/op/services/resources/,swaggerConfig=null,
>>> usePathBasedConfig=null and then calls
>>> SwaggerContextService.getSwagger()
>>> which returns the Swagger definition for interface KmopApiServer?
>>> It looks like it caches generated swagger definitions based on a
>>> configIdKey with prefix ’swagger.config.id.xxx’. This key is the
>>> same for all 3 interfaces as usePathBasedConfig=null
>>> and maps to ‘swagger.config.id.default’. The usePathBasedConfig is
>>> derived from the ServletConfig parameter
>>> ‘swagger.use.path.based.config’.* So should this be set on the
>>> declaration of the CXFServlet** in web.xml?*
>>> è Actually the SwaggerConfig, the JaxrsScanner and the generated
>> Swagger
>>> are cached using keys like
>>> ‘swagger.config.id.[default|baseUriPath]’, ‘
>>> scanner.config.id.[default|baseUriPath]’. Caching with ‘baseUriPath’
>> is only done when usePathBasedconfig=true.
>>> è If I patch this to true then configIdKey=’
>>> swagger.config.id./op/services/resources/’ and no swagger entry is
>>> cached for this key so it will generate a new one. Again by
>>> patching
>>> SwaggerContextService.isUsePathBasedConfigInitParamDefined(sc)=tru
>>> e
>>> it will call: “swagger = scan(app, servletContext, sc, uriInfo);”
>>> è Again Scanners are cached and if usePathBasedConfig=null it
>> will use
>>> the one cached under ‘swagger.scanner.id.default’ and this again
>>> returns the swagger definition for the KmopApiService interface.
>>> è So patching usePathBasedConfig=true will return a new one
>>> (DefaultJaxrsScanner). The classes to scan for in this new scanner
>>> are ‘ be.dvtm.aeo.op.openapi.api.impl.KmopResourcesApiServiceImpl‘
>>> which is correct. It will generate a new (but empty) Swagger object.
>>> è Next Swagger2ApiListingResource will call the
>>> customizer.customize(s), which still isn’t putting anything new in
>>> the Swagger object. Should it or should the next step do this?
>>> è Next BaseApiListingResource#getListing(…) is called which on
>> its
>>> turn calls getListingYamlResponse(..)
>>> è The final result is a swagger.yaml document with following
>> content:
>>> swagger: "2.0"
>>> info:
>>> license:
>>> name: "Apache 2.0 License"
>>> url: http://www.apache.org/licenses/LICENSE-2.0.html
>>> basePath: "/op/services/resources"
>>> So basically an empty swagger file.
>>> d) The usePathBasedConfig is derived from the ServletConfig
>> parameter ‘
>>> swagger.use.path.based.config’. Without this parameter set to true
>>> there will be only one Swaggerconfig, JaxrsScanner and Swagger
>>> object.* So should this be set on the declaration of the
>>> CXFServlet** in web.xml?*
>>> The majority in this processing happens in the library
>>> swagger-jaxrs-v1.6.10 which is included as a dependency on
>> cxf-rt-rs-service-description-swagger.
>>> Even if I patch usePathBasedConfig=true about everywhere where I
>>> met this it still doesn’t generate a correct swagger.yaml. Am I
>>> still missing some configuration parameter?
>>> Any suggestions on how to resolve this would be welcome.
>>> Regards,
>>> J.P. Urkens
>>> <<...>> <<...>>
>>> -----Original Message-----
>>> From: Andriy Redko <[email protected]>
>>> Sent: maandag 8 mei 2023 23:15
>>> To: Jean Pierre URKENS <[email protected]>; CXF Dev
>>> List <
>>> Subject: Re: How to setup multiple JAXRS server endpoints
>>> Hi Jean,
>>> Indeed the way you would like to do that is somewhat tricky.
>>>> So I tried to keep the @Path declaration on the interface classes
>>>> but
>>> changed them to @Path(“”). That does seems to work except the
>>> swagger stuff no longer correctly works.
>>> This is one of the possible options but OpenAPI/Swagger gets
>>> confused for a
>>> reason: the path is now implicit (not in the spec).
>>> So how about this option:
>>> - use only one JAX-RS server (address "/")
>>> - host both resources but use @Path("accounts") and
>>> @Path("resources") on them respectively
>>> I see that for @Path("accounts") you need to apply the
>>> "kmopApiAuthorizationFilter", that could be done using
>>> DynamicFeature [1], [2]. If this is not the option and you would
>>> prefer to use 2 separate JAX-RS servers, you may need to provide
>>> your own instance of Swagger2Customizer [3], [4] which allows to
>>> transform the OpenAPI/Swagger on the fly. Please let me know if
>>> that
>> would it work for you, thank you.
>>> [1]
>>> https://docs.oracle.com/javaee/7/api/javax/ws/rs/container/Dynamic
>>> F
>>> eature.html
>>> [2]
>>> https://aredko.blogspot.com/2016/02/your-jax-rs-apis-were-not-born
>>> -
>>> equal.html
>>> [3]
>>> https://cxf.apache.org/javadoc/latest/org/apache/cxf/jaxrs/swagger
>>> /
>>> Swagger2Customizer.html
>>> [4] https://cxf.apache.org/docs/swagger2feature.html (has
>>> customizer
>>> property)
>>> Best Regards,
>>> Andriy Redko
>>>> Hi Andriy,
>>>> I am again getting into trouble with server endpoint declarations.
>>>> Now
>>> because I am adding additional JAX-RS endpoints.
>>>> The issue is with:
>>>> 1. The 'address' attribute on the <jaxrs:server> declaration in
>>> combination with
>>>> 2. The 'url-pattern' for the CXFServlet declaration in the web.xml
>>> in combination with
>>>> 3. The @Path declaration in the interface class in combination with
>>>> 4. The @Path declaration on the interface method in combination
> with
>>>> So what I had is that my web application deployed under baseUlr 'op'
>>>> had
>>> one JAXRS server endpoint with declarations like:
>>>> 1. <jaxrs:server id="restServer"
>>> basePackages="be.dvtm.aeo.op.sodexo" address="/">
>>>> 2. <url-pattern>/services/*</url-pattern>
>>>> 3. @Path("accounts") on the public interface class
>>>> 4. @Path("/{authorisationId}/customerFund") on the customerFund
>>> interface method
>>>> A valid API call would thus be e.g.:
>>>> https://<hostname>:<port>/op/services/accounts/{authorizationId}/cus
>>>> t
>>>> o
>>>> merFund
>>>> And this works correctly.
>>>> We're now introducing additional JAX-RS service endpoints and now I
>>>> am
>>> running into problems. This second endpoint was declared with:
>>>> 1. <jaxrs:server id="resourceServer"
>>> basePackages="be.dvtm.aeo.op.resources" address="/">
>>>> 2. <url-pattern>/services/*</url-pattern>
>>>> 3. @Path("resources") on the public interface class
>>>> 4. @Path("/NACE") on the NACE interface method
>>>> So here a valid API call woud be:
>>> https://<hostname>:<port>/op/services/resources/NACE.
>>>> The problem is that I can not declare two <jaxrs:server> entries
>>>> with
>>>> the
>>> same ‘address’ as it throws the exception:
>>>> Caused by: org.apache.cxf.service.factory.ServiceConstructionException:
>>> There is an endpoint already running on /.
>>>> So I tried changing the addresses to:
>>>> · address=”accounts” for the restServer
>>>> · address=”resources” for the resourceServer
>>>> But to keep the API-call URLs the same I removed the @Path
>>>> declaration on
>>> the interface classes. By doing so the <jaxrs:server> bean
>>> declarations no longer loads successfully.
>>>> So I tried to keep the @Path declaration on the interface classes
>>>> but
>>> changed them to @Path(“”). That does seems to work except the
>>> swagger stuff no longer correctly works.
>>>> So what is the decent way to setup multiple JAX-RS server endpoints
>>>> where
>>> each server has its own configuration regarding supported features:
>>>> · own validation
>>>> · own object and exception mappings
>>>> · own swagger file generation
>>>> · own logging (in separate file if possible)
>>>> I am using Apache CXF-3.5.2 which uses swagger-core v1.6.6 in
>>>> cooperation
>>> with swager-ui v4.5.0.
>>>> Below the declarations of my endpoints <<...>> Thanks for any advice.
>>>> Regards,
>>>> J.P. Urkens
>>>> -----Original Message-----
>>>> From: Andriy Redko <[email protected]>
>>>> Sent: zaterdag 18 juni 2022 1:12
>>>> To: Jean Pierre URKENS <[email protected]>;
>>>> [email protected]; [email protected]
>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi Jean,
>>>>> 1. a jaxrs server on url: '/<basePath>/services/service1'
>>>> Correct, so in the relative form like address="/<something>", the
>>>> JAX-RS
>>> endpoint path would be:
>>>> <baseUrl>/<servlet path
mapping>>>>>/<address>/[@ApplicationPath]/[@Path]
>>>> The @ApplicationPath is optional in this case.
>>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'
>>>> The JAX-WS is very different from JAX-RS, essentially the action
>>>> comes
>>> inside the SOAP message behind <baseUrl>/<servlet path mapping>/
>>> (@Path / @ApplicationPath are not relevant there).
>>>>> Question: Because now address="/" is set for the jaxrs:server will
>>>>> it
>>>>> also inspect requests targeted for the jaxws service as those
>>>>> requests have start with the same path '/<basePath>/services/...
>>>> This is a good question, I have not done it myself but I think it
>>>> should
>>> work:
>>>> the servlet dispatches according to registered services, in this
>>>> regard
>>> JAX-RS and JAX-WS should not conflict. Does it work in your case?
>> Thank you.
>>>> Best Regards,
>>>> Andriy Redko
>>>>> Hi Andriy,
>>>>> Using address="/" seems to work but still I don't understand how
>>>>> the
>>>>> following work together:
>>>>> - path specification in servlet mapping for the CXF servlet
>>>>> (org.apache.cxf.transport.servlet.CXFServlet)
>>>>> - the 'address' attribute on the jaxrs:server bean declaration
>>>>> - the javax.ws.rs.Path or javax.jws.WebService annotation on the
>>>>> service API description Say I've two services with (relateive to
>>>>> the
>>>>> host) url's:
>>>>> 1. a jaxrs server on url: '/<basePath>/services/service1'
>>>>> 2. a jaxws service endpoint on '/<basePath>/services/service2'
>>>>> How do I configure above 3 aspects? Currently I have (working):
>>>>> 1.for the jaxrs:server endpoint:
>>>>> - servlet path mapping: '/services/*'
>>>>> - jaxrs-server address attribute: address="/"
>>>>> - @Path annotation: @Path("service1") 2.For the
>>>>> jaxws
>>>>> service endpoint:
>>>>> - servlet path mapping: '/services/*' (JAXWS and JAXRS
>>>>> requests are handleb by the same CXF servle)
>>>>> - jaxws:endpoint server address attribute:
>>>>> address="/service2"
>>>>> - @WebService(name="service2") A correct request for
>>>>> '1' would be '/basePath>/services/service1/<ID>'.
>>>>> A correct request for '2' would be '/basePath>/services/service2'.
>>>>> The jaxrs/jaxws configuration behavior seem to differ with respect to:
>>>>> - the server address attribute
>>>>> - The API annotation (@Path or @Webservice) The JAXWS
>>>>> server
>>>>> address attribute doesn't seem to interfere with the @Webservice
>>>>> annotation. While the jaxrs server address attribute does seem to
>>>>> interfere with the @Path annotation. I would have expected the
>>>>> jaxrs
>>>>> server aspects to be configured as:
>>>>> - servlet path mapping: '/services/*'
>>>>> - jaxrs-server address attribute: address="/service1"
>>>>> - @Path annotation: @Path("service1") but then a
>>>>> valid
>>>>> request would be
>>>>>> /services/service1/service1/<ID>'.
>>>>> For both the 'address' attribute is relative to the servlet path.
>>>>> The @Path Javadoc mentions that this path is relative to the
>>>>> ApplicationPath which thus seems to be relative to the jaxrs-server
>>>>> address attribute. As for @Webservice it doesnn't seem to be
>>>>> url-path
>>> related.
>>>>> Question: Because now address="/" is set for the jaxrs:server will
>>>>> it
>>>>> also inspect requests targeted for the jaxws service as those
>>>>> requests have start with the same path '/<basePath>/services/...'.
>>>>> Albeit somewhat confusing.
>>>>> J.P.
>>>>> -----Original Message-----
>>>>> From: Andriy Redko <[email protected]>
>>>>> Sent: dinsdag 14 juni 2022 1:08
>>>>> To: Jean Pierre URKENS <[email protected]>;
>>>>> [email protected]; [email protected]
>>>>> Subject: Re: JAXRS server endpoint not gracefully shutdown Hi Jean,
>>>>> Indeed, the jaxrs:server does not expect address to be omitted, you
>>>>> could use the "/" (and I believe an empty string would also make it):
>>>>> <jaxrs:server id="restServer" basePackages="xxx" address="/"> ...
>>>>> </jaxrs:server>
>>>>> Thank you.
>>>>> Hope it helps.
>>>>> Best Regards,
>>>>> Andriy Redko
>>>>>> I create a JAXRS server endpoint (CXF 3.5.2) using spring bean
>>>>>> declarations
>>>>>> like:
>>>>>> <jaxrs:server id="restServer" basePackages="xxx">
>>>>>> <jaxrs:serviceBeans>
>>>>>> <ref bean="TestApi" />
>>>>>> </jaxrs:serviceBeans>
>>>>>> <jaxrs:providers>
>>>>>> <…/>
>>>>>> </jaxrs:providers>
>>>>>> <jaxrs:features>
>>>>>> <… />
>>>>>> </jaxrs:features>
>>>>>> <jaxrs:inInterceptors>
>>>>>> <… />
>>>>>> </jaxrs:inInterceptors>
>>>>>> <jaxrs:outInterceptors>*
>>>>>> <**…**/>*
>>>>>> </jaxrs:outInterceptors>*
>>>>>> </jaxrs:server>
>>>>>> Here my “TestApi” bean interface is declared like:
>>>>>> @Path("accounts")
>>>>>> @Consumes(MediaType.*APPLICATION_JSON*)
>>>>>> @Produces(MediaType.*APPLICATION_JSON*)
>>>>>> public interface TestApi {
>>>>>> …
>>>>>> }
>>>>>> And CXF is triggered via a servlet configuration like:
>>>>>> <servlet>
>>>>>> <display-name>CXF Servlet</display-name>
>>>>>> <servlet-name>CXFServlet</servlet-name>
>>>>>> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servle
>>>>>> t
>>>>>> </servlet>
>>>>>> <servlet-mapping>
>>>>>> <servlet-name>CXFServlet</servlet-name>
>>>>>> <url-pattern>/services/*</url-pattern>
>>>>>> </servlet-mapping>
>>>>>> Because I’ve got the @Path declaration on the interface type I’ve
>>>>>> omitted
>>>>>> the address=”accounts” attribute on the jaxrs:server declaration
>>>>>> since otherwise
>>>>>> I noticed that the server would be listening to
>>>>>> /basepath/services/ accounts/accounts/…).
>>>>>> Now this configuration works perfectly, only when shutting down
>>>>>> the application server cxf calls
>>>>>> ServerImpl#destroy()
>>>>>> which delegates (via Obeservable) to
>>>>>> AbstractHTTPDestination#deactivate()
>>>>>> which calls
>>>>>> registry.removeDestination(path).
>>>>>> This path is null (no ‘address’ specified on jaxrs:server
>>>>>> declaration) and results in a NPE on the registry Map.
>>>>>> This causes an unclean shutdown of my server.
>>>>>> Is this an error in cxf or is my jaxrs:server configured incorrectly?
>>>>>> How does the ‘address’ attribute on the jaxrs:server declaration
>>>>>> correctly interact with the @Path parameter on the API interface?
>>> <<...>>