I’ve been debugging this and at the moment that Spring is invoking the
SpringJAXRSServerFactoryBean#create()  method for the ‘jqdtoRestServer’
bean to create the endpoint the

serviceFactory.getRealClassResourceInfo() returns an empty list upon which
AbstractJAXRSFactoryBean#checkResources(true) fails.



The classResourceInfos member on the JAXRSServiceFactoryBean is not set,
neither are the JAXRSServerFactoryBean#service, JAXRSServerFactoryBean
#serviceName members set (which would cause resources to be added to the
classResourceInfos member), however
SpringJAXRSServerFactoryBean#serviceBeansAvailable=true.



Where/why is this initialization going wrong?





*From:* Jean Pierre URKENS <jean-pierre.urk...@devoteam.com>
*Sent:* vrijdag 30 september 2022 9:51
*To:* 'users@cxf.apache.org' <users@cxf.apache.org>
*Subject:* JAXRS ServiceConstructionException: No resource classes found



I am struggling with getting a JAXRS service up-and-running although it is
with regard to its setup identical to another JAXRS service that I’ve setup
successfully.



I am using:

   - CXF v3.5.2
   - Spring v3.2.18 (legacy reasons)
   - Jackson 2.13.1

My service description is defined in a yaml-file using the openapi v3.0.3
specification. From this the interface,implementation and model classes
where generated using the

maven plugin ‘org.openapitools:openapi-generator-maven-plugin:6.2.0’ with
generatorName=’jaxrs-cxf’.

Basically the service interface class looks like:



@Path("/jqdto")

@Api(value = "/", description = "stripped")

@Consumes(MediaType.*APPLICATION_JSON*)

@Produces(MediaType.*APPLICATION_JSON*)

*public* *interface* JqDtoApi {

         @POST

         @Path("/getData")

         @Consumes({ "application/json" })

         @Produces({ "application/json" })

         @ApiOperation(value = "stripped", tags = { "JQDto" })

         @ApiResponses(value = {

                          @ApiResponse(code = 200, message = "Success",
response = JQDTOResponse.*class*),

                          @ApiResponse(code = 400, message = "Refused\\",
response = ErrorResponse.*class*),

                          @ApiResponse(code = 401, message = "Unauthorized")
})

         Response *getData*(ContainerRequestContext requestContext,@Valid
@NotNull JQDTORequest jqDTORequest);

}



And the implementation class looks like:

@Service("JqDtoApi")

*public* *class* JqDtoApiServiceImpl *implements* JqDtoApi {

         @Override

         *public* Response *getData*(@Context ContainerRequestContext
requestCtx,JQDTORequest jqDTORequest) {

         /** implementation */

         }

}



The service endpoint is declared in an xml-file looking like:

<?xml version="1.0" encoding="UTF-8"?>

<beans  xmlns=http://www.springframework.org/schema/beans

                                  xmlns:xsi=
http://www.w3.org/2001/XMLSchema-instance

                                  xmlns:cxf=http://cxf.apache.org/core

                                  xmlns:jaxrs=http://cxf.apache.org/jaxrs

                                  xmlns:jee=
http://www.springframework.org/schema/jee

                                   xmlns:context=
http://www.springframework.org/schema/context

         xsi:schemaLocation="

                                  http://cxf.apache.org/core
http://cxf.apache.org/schemas/core.xsd

                                  http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd

                                  http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd


http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd


http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd

                                  http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee.xsd";>



         <import resource="classpath:META-INF/cxf/cxf.xml" />

         <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />



         *<!--    JAXRS providers -->*

         <bean id="jsonProvider" class=
"com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider">

                 <constructor-arg index="0">

                          <bean class=
"be.dvtm.aeo.common.data.jqdto.mapper.CustomObjectMapper"/>

                 </constructor-arg>

                 <constructor-arg index="1" value="#{
T(com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider).BASIC_ANNOTATIONS }"
/>

         </bean>



         *<!-- CXF Swagger2Feature -->*

         <bean id="SwaggerUiConfig" class=
"org.apache.cxf.jaxrs.swagger.ui.SwaggerUiConfig">

                 <property name="queryConfigEnabled" value="false"/>

                 <property name="url" value="services/swagger.yaml"/>

         </bean>

         <bean id="swagger2Feature" class=
"org.apache.cxf.jaxrs.swagger.Swagger2Feature">

                 <property name="basePath" value="/services"/>

                 <property name="supportSwaggerUi" value="true" />

                 <property name="swaggerUiConfig" ref="SwaggerUiConfig"/>

         </bean>



         *<!-- CXF Bean validation -->*

         <bean id="exceptionMapper" class=
"be.dvtm.aeo.common.data.jqdto.mapper.CustomExceptionMapper" />

         <bean id="validationProvider" class=
"org.apache.cxf.validation.BeanValidationProvider" />

         <bean id="validationInInterceptor" class=
"org.apache.cxf.jaxrs.validation.JAXRSBeanValidationInInterceptor">

                 <property name="provider" ref="validationProvider" />

         </bean>

         <bean id="validationOutInterceptor" class=
"org.apache.cxf.jaxrs.validation.JAXRSBeanValidationOutInterceptor">

                 <property name="provider" ref="validationProvider" />

         </bean>



         <bean id="JqDtoApi" class=
"be.dvtm.aeo.common.data.jqdto.api.impl.JqDtoApiServiceImpl">

                 <description>JQuery Datatable endpoint service
implementation</description>

         </bean>

         <bean id="cxf.wiremessage.logging" class=
"org.apache.cxf.ext.logging.LoggingFeature">

                 <property name="prettyLogging" value="false" />

         </bean>



         *<!-- JQDto REST API endpoint server -->*

         <jaxrs:server id="jqdtoRestServer" basePackages=
"be.dvtm.aeo.common.data.jqdto" address="/">

                 <jaxrs:serviceBeans>

                          <ref bean="JqDtoApi" />

                 </jaxrs:serviceBeans>

                 <jaxrs:providers>

                          <ref bean="jsonProvider" />

                          <ref bean="exceptionMapper"/>

                 </jaxrs:providers>

                 <jaxrs:features>

                          <ref bean="swagger2Feature" />

                          <ref bean="cxf.wiremessage.logging" />

                 </jaxrs:features>



                 <jaxrs:inInterceptors>

                          <ref bean="validationInInterceptor" />

                 </jaxrs:inInterceptors>

         </jaxrs:server>

</beans>



The service is deployed in a Tomcat 8.5 environment using the
org.apache.cxf.transport.servlet.CXFServlet class to handle incoming
requests.

When starting the server I can see the springframework bean classes
AbstractBeanFactory, AbstractAutowireCapableBeanFactory  and
DefaultSingletonBeanRegistry creating all beans for my service as listed in
the endpoint declaration file above (including those used within the
service implementation class). However when it starts to create the
jqdtoRestServer server it fails in the end because he can’t find (or
identify) the resource classes. I guess it needs to resolve the classes
JqDtoApi, JqDtoApiServiceImpl ,…

All these classes exist and beans are created for them. The implementation
class is annotated with the org.springframework.stereotype.Service  annotation
(I tried putting it on the interface class but didn’t work either).



All this is similar to another CXF JAXRS service I’ve setup and that is
up-and-running. So why am I getting a “ServiceConstructionException:no
resource classes found” error?



Below the log extract from the moment the 'jqdtoRestServer'is created.



[IDB-BE] 2022-09-30 08:42:19,734 [localhost-startStop-1] DEBUG $--$
(org.springframework.beans.factory.support.DefaultSingletonBeanRegistry:215)
- Creating shared instance of singleton bean 'jqdtoRestServer'

[IDB-BE] 2022-09-30 08:42:19,734 [localhost-startStop-1] DEBUG $--$
(org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory:430)
- Creating instance of bean 'jqdtoRestServer'

[IDB-BE] 2022-09-30 08:42:19,745 [localhost-startStop-1] DEBUG $--$
(org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory:504)
- Eagerly caching bean 'jqdtoRestServer' to allow for resolving potential
circular references

[IDB-BE] 2022-09-30 08:42:19,745 [localhost-startStop-1] TRACE $--$
(org.springframework.beans.CachedIntrospectionResults:265) - Getting
BeanInfo for class
[org.apache.cxf.jaxrs.spring.JAXRSServerFactoryBeanDefinitionParser$SpringJAXRSServerFactoryBean]

[IDB-BE] 2022-09-30 08:42:19,763 [localhost-startStop-1] TRACE $--$
(org.springframework.beans.CachedIntrospectionResults:298) - Caching
PropertyDescriptors for class
[org.apache.cxf.jaxrs.spring.JAXRSServerFactoryBeanDefinitionParser$SpringJAXRSServerFactoryBean]

[IDB-BE] 2022-09-30 08:42:19,763 [localhost-startStop-1] TRACE $--$
(org.springframework.beans.CachedIntrospectionResults:311) - Found bean
property 'address' of type [java.lang.String]

[IDB-BE] 2022-09-30 08:42:19,767 [localhost-startStop-1] DEBUG $--$
(org.springframework.beans.factory.support.AbstractBeanFactory:243) -
Returning cached instance of singleton bean 'JqDtoApi'

[IDB-BE] 2022-09-30 08:42:19,767 [localhost-startStop-1] DEBUG $--$
(org.springframework.beans.factory.support.AbstractBeanFactory:243) -
Returning cached instance of singleton bean 'jsonProvider'

[IDB-BE] 2022-09-30 08:42:19,767 [localhost-startStop-1] DEBUG $--$
(org.springframework.beans.factory.support.AbstractBeanFactory:243) -
Returning cached instance of singleton bean 'exceptionMapper'

[IDB-BE] 2022-09-30 08:42:19,767 [localhost-startStop-1] DEBUG $--$
(org.springframework.beans.factory.support.AbstractBeanFactory:243) -
Returning cached instance of singleton bean 'swagger2Feature'

[IDB-BE] 2022-09-30 08:42:19,767 [localhost-startStop-1] DEBUG $--$
(org.springframework.beans.factory.support.AbstractBeanFactory:243) -
Returning cached instance of singleton bean 'cxf.wiremessage.logging'

[IDB-BE] 2022-09-30 08:42:19,767 [localhost-startStop-1] DEBUG $--$
(org.springframework.beans.factory.support.AbstractBeanFactory:243) -
Returning cached instance of singleton bean 'validationInInterceptor'

[IDB-BE] 2022-09-30 08:42:19,768 [localhost-startStop-1] DEBUG $--$
(org.springframework.beans.factory.support.AbstractBeanFactory:243) -
Returning cached instance of singleton bean 'cxf'

[IDB-BE] 2022-09-30 08:42:19,825 [localhost-startStop-1] DEBUG $--$
(org.springframework.core.io.support.PathMatchingResourcePatternResolver:467)
- Looking for matching resources in jar file
[file:/F:/Tools/apache-tomcat-8.5.43/nodes/node2/webapps/idb-be/WEB-INF/lib/AEO-Common-Data-JQDTO-1.0.0-SNAPSHOT.jar]

[IDB-BE] 2022-09-30 08:42:19,826 [localhost-startStop-1] DEBUG $--$
(org.springframework.core.io.support.PathMatchingResourcePatternResolver:354)
- Resolved location pattern [ ***stripped, looks ok to me ***]]

[IDB-BE] 2022-09-30 08:42:19,843 [localhost-startStop-1] DEBUG $--$
(org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory:430)
- Creating instance of bean
'be.dvtm.aeo.common.data.jqdto.api.impl.JqDtoApiServiceImpl'

[IDB-BE] 2022-09-30 08:42:19,844 [localhost-startStop-1] DEBUG $--$
(org.springframework.beans.factory.support.AbstractBeanFactory:243) -
Returning cached instance of singleton bean
'org.springframework.transaction.config.internalTransactionAdvisor'

[IDB-BE] 2022-09-30 08:42:19,845 [localhost-startStop-1] DEBUG $--$
(org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory:458)
- Finished creating instance of bean
'be.dvtm.aeo.common.data.jqdto.api.impl.JqDtoApiServiceImpl'

[IDB-BE] 2022-09-30 08:42:19,845 [localhost-startStop-1] DEBUG $--$
(org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory:430)
- Creating instance of bean
'be.dvtm.aeo.common.data.jqdto.mapper.ObjectMapperContextResolver'

[IDB-BE] 2022-09-30 08:42:19,845 [localhost-startStop-1] TRACE $--$
(org.springframework.beans.CachedIntrospectionResults:265) - Getting
BeanInfo for class
[be.dvtm.aeo.common.data.jqdto.mapper.ObjectMapperContextResolver]

[IDB-BE] 2022-09-30 08:42:19,849 [localhost-startStop-1] TRACE $--$
(org.springframework.beans.CachedIntrospectionResults:298) - Caching
PropertyDescriptors for class
[be.dvtm.aeo.common.data.jqdto.mapper.ObjectMapperContextResolver]

[IDB-BE] 2022-09-30 08:42:19,850 [localhost-startStop-1] TRACE $--$
(org.springframework.beans.CachedIntrospectionResults:311) - Found bean
property 'class' of type [java.lang.Class]

[IDB-BE] 2022-09-30 08:42:19,850 [localhost-startStop-1] DEBUG $--$
(org.springframework.beans.factory.support.AbstractBeanFactory:243) -
Returning cached instance of singleton bean
'org.springframework.transaction.config.internalTransactionAdvisor'

[IDB-BE] 2022-09-30 08:42:19,850 [localhost-startStop-1] DEBUG $--$
(org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory:458)
- Finished creating instance of bean
'be.dvtm.aeo.common.data.jqdto.mapper.ObjectMapperContextResolver'

[IDB-BE] 2022-09-30 08:42:19,850 [localhost-startStop-1] DEBUG $--$
(org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory:1614)
- Invoking init method  'create' on bean with name 'jqdtoRestServer'

[IDB-BE] 2022-09-30 08:42:19,851 [localhost-startStop-1] WARN  $--$
(org.springframework.context.support.AbstractApplicationContext:490) -
Exception encountered during context initialization - cancelling refresh
attempt: org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'jqdtoRestServer': Invocation of init method
failed; nested exception is
org.apache.cxf.service.factory.ServiceConstructionException

[IDB-BE] 2022-09-30 08:42:19,851 [localhost-startStop-1] INFO  $--$
(org.springframework.beans.factory.support.DefaultSingletonBeanRegistry:444)
- Destroying singletons in
org.springframework.beans.factory.support.DefaultListableBeanFactory@133ae78d:
defining beans []; root of factory hierarchy

[IDB-BE] 2022-09-30 08:42:19,851 [localhost-startStop-1] DEBUG $--$
(org.springframework.beans.factory.support.DisposableBeanAdapter:303) -
Invoking destroy method 'close' on bean with name 'validationOutInterceptor'

[IDB-BE] 2022-09-30 08:42:19,851 [localhost-startStop-1] DEBUG $--$
(org.springframework.beans.factory.support.DisposableBeanAdapter:303) -
Invoking destroy method 'close' on bean with name 'validationInInterceptor'

[IDB-BE] 2022-09-30 08:42:19,851 [localhost-startStop-1] DEBUG $--$
(org.springframework.beans.factory.support.DisposableBeanAdapter:303) -
Invoking destroy method 'close' on bean with name 'validationProvider'

[IDB-BE] 2022-09-30 08:42:19,851 [localhost-startStop-1] DEBUG $--$
(org.springframework.beans.factory.support.DefaultSingletonBeanRegistry:500)
- Retrieved dependent beans for bean
'be.dvtm.aeo.common.data.jqdto.mapper.CustomObjectMapper#59b31630':
[jsonProvider]

[IDB-BE] 2022-09-30 08:42:19,856 [localhost-startStop-1] ERROR $--$
(org.springframework.web.context.ContextLoader:331) - Context
initialization failed

org.springframework.beans.factory.BeanCreationException: Error creating
bean with name 'jqdtoRestServer': Invocation of init method failed; nested
exception is org.apache.cxf.service.factory.ServiceConstructionException

                    at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1514)

                    at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)

                    at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)

                    at
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)

                    at
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)

                    at
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)

                    at
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:191)

                    at
org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:638)

                    at
org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:942)

                    at
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)

                    at
org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:410)

                    at
org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)

                    at
org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)

                    at
org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4699)

                    at
org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5165)

                    at
org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)

                    at
org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:743)

                    at
org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:719)

                    at
org.apache.catalina.core.StandardHost.addChild(StandardHost.java:714)

                    at
org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1125)

                    at
org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1859)

                    at
java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)

                    at java.util.concurrent.FutureTask.run(Unknown Source)

                    at
java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)

                    at
java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

                    at java.lang.Thread.run(Unknown Source)

Caused by: org.apache.cxf.service.factory.ServiceConstructionException

                    at
org.apache.cxf.jaxrs.JAXRSServerFactoryBean.create(JAXRSServerFactoryBean.java:220)

                    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native
Method)

                    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown
Source)

                    at
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

                    at java.lang.reflect.Method.invoke(Unknown Source)

                    at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeCustomInitMethod(AbstractAutowireCapableBeanFactory.java:1640)

                    at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1581)

                    at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1511)

                    ... 25 more

Caused by: org.apache.cxf.service.factory.ServiceConstructionException: No
resource classes found

                    at
org.apache.cxf.jaxrs.AbstractJAXRSFactoryBean.checkResources(AbstractJAXRSFactoryBean.java:318)

                    at
org.apache.cxf.jaxrs.JAXRSServerFactoryBean.create(JAXRSServerFactoryBean.java:156)

                    ... 32 more

Reply via email to