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/DynamicFeature.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}/customerFund
> 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
-class>>>>
>>> </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?