Programmatically configure Jersey Application - java

I am trying to configure my Jersey application using my own Application implementation or an extended ResourceConfig or PackageResourceConfig. So, my first attempt consists in porting an exisiting web.xml (actually I'm using web-fragment.xml because of library nature of my development) configuration to MyApplication implementation.
This is the working web-fragment.xml before porting
<servlet>
<servlet-name>rest</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>my.pkg.resources;org.codehaus.jackson.jaxrs</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
<param-value>my.pkg.Filter1;my.pkg.Filter2</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>rest</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
Below, modified web-fragment.xml
<servlet>
<servlet-name>my.pkg.MyApplication</servlet-name> <!-- implementation follows -->
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>my.pkg.MyApplication</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
and MyApplication class
// [...]
public class MyApplication extends PackagesResourceConfig {
private static final Logger logger = Logger.getLogger(MyApplication.class);
#Context
ServletConfig config
public MyApplication() {
super("my.pkg.resources;org.codehaus.jackson.jaxrs");
super.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
// filters not set
}
#PostConstruct
public void readInitParams() {
// read init params from ServletConfig
// config.getInitParameterNames();
// ...
}
}
Anytime I use the second version, I receive the following
mag 27, 2013 12:08:03 PM com.sun.jersey.api.core.PackagesResourceConfig init
INFO: Scanning for root resource and provider classes in the packages:
aero.aice.jerico.rs;org.codehaus.jackson.jaxrs;
mag 27, 2013 12:08:03 PM com.sun.jersey.server.impl.application.DeferredResourceConfig$ApplicationHolder <init>
INFO: Instantiated the Application class my.package.MyApplication. The following root resource and provider classes are registered: [class com.sun.jersey.server.impl.application.WebApplicationImpl$1WadlContextResolver, class org.codehaus.jackson.jaxrs.JsonParseExceptionMapper, class org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider, class org.codehaus.jackson.jaxrs.JsonMappingExceptionMapper, class aero.aice.jerico.rs.service.OperationService, class aero.aice.jerico.rs.service.CrudService, class org.codehaus.jackson.jaxrs.JacksonJsonProvider]
mag 27, 2013 12:08:03 PM com.sun.jersey.core.spi.component.ProviderFactory __getComponentProvider
SEVERE: The provider class, class com.sun.jersey.server.impl.application.WebApplicationImpl$1WadlContextResolver, could not be instantiated. Processing will continue but the class will not be utilized
java.lang.InstantiationException: com.sun.jersey.server.impl.application.WebApplicationImpl$1WadlContextResolver
mag 27, 2013 12:08:04 PM com.sun.jersey.spi.inject.Errors processErrorMessages
SEVERE: The following errors and warnings have been detected with resource and/or provider classes:
SEVERE: The class com.sun.jersey.server.impl.application.WebApplicationImpl$1WadlContextResolver is a not a public class and cannot be instantiated.
SEVERE: The inner class com.sun.jersey.server.impl.application.WebApplicationImpl$1WadlContextResolver is not a static inner class and cannot be instantiated.
As you can see, com.sun.jersey.server.impl.application.WebApplicationImpl$1WadlContextResolver is the first registered class but that is not instantiable because it is not public and not a static inner class.
I have found very little documentation about this procedure and in particular, how to set features and properties during initialization.
I am using the last available version of Jersey (1.17.1) but have tested with 1.9 too.
Is it also possible to set application path, programatically? I have seen #ApplicationPath in documentation but it is not useful for my purpose because i need to set it at runtime.
I know these are more questions but I think they all lead to the same root.
Can anybody point me to the right direction?

Make sure you have no jersey libs on path which is scanned for resource classes.
Base URI you can set only during deployment. Using war name or #ApplicationPath. You can override it using servlet-mapping element in the web.xml.

I had go through similar problem:
SEVERE: The class com.sun.jersey.server.impl.application.WebApplicationImpl$1WadlContextResolver is a not a public class and cannot be instantiated.
SEVERE: The inner class com.sun.jersey.server.impl.application.WebApplicationImpl$1WadlContextResolver is not a static inner class and cannot be instantiated.
This error freaked me out... Basically I am using GlassFish 3.x. It has already one jersey.core.jar included. But I needed a jersey-server lib. My libs was:
jersey.core.jar -> MANIFEST.MF -> 1.11.1
jersey-server-1.17.1
My problem was I mixed JARs from different Jersey versions. When I go for jersey-server-1.11.1 I don't see this error anymore.

Related

OSGi Equinox + Jetty - simple REST deploy using web.xml

Trying a simple REST implementation on OSGi Equinox + Jetty - simple REST deploy using web.xml
Below are the details of my implementation:
Resource file:
#Path("jsonstatus")
public class JsonResource {
private static Logger logger = LoggerFactory.getLogger(JsonResource.class);
#GET
#Produces("application/json")
public String listConferences() {
logger.info("Returning the status");
return "{\"status\": \"success\"}";
}
}
Application Implementation:
public class JerseyApplication extends Application {
private static Logger logger = LoggerFactory.getLogger(JerseyApplication.class.getName());
#Override
public Set<Class<?>> getClasses() {
logger.info("--Returning all the claess-");
Set<Class<?>> result = new HashSet<Class<?>>();
result.add(JsonResource.class);
result.add(StatusResource.class);
return result;
}
}
web.xml:
<servlet>
<servlet-name>SimpleREST</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>my.learnings.osgi.rest.jetty.activator.JerseyApplication</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SimpleREST</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
All the OSGi core, console and jetty jars are added: When I start the Equinox, i get the below error. I dont have the activator mapped to bundle when i deployed using web.xml
But with activator and web.xml removed, REST API works, No error during equinox startup.
Simple Activator:
#Override
public void start(BundleContext context) throws Exception {
logger.info("Starting the bundle");
ServletContextHandler ch = new ServletContextHandler();
ch.setContextPath("/");
ServletHolder holder = new ServletHolder(new ServletContainer());
holder.setInitParameter("javax.ws.rs.Application", JerseyApplication.class.getName());
ch.addServlet(holder, "/*");
context.registerService(ContextHandler.class.getName(), ch, null);
}
When searched in the internet, i saw, need to configure JNDI, This is very basic simple REST which does not require a database. So got confused why we need JNDI. Some article discussed about initialization of the java.naming.factory.initial. But those are given for jboss. Not sure how to configure the initial context for jetty.All the combinations i tried are in the github code.
If you could help to get the initial context configured in the OSGi-jetty would really a great help. I am looking for a deployment with web.xml way of servlet creation on OSGi with jetty
Below repository contains the code which I tried:
https://github.com/pkolanda/my-learning-osgi-simple-rest-with-jetty
to run the code, mvn clean install and run the run.sh shell script under the target/my-learning-osgi-simple-rest-with-jetty-0.1 folder.
Meanwhile i am looking into this post
Log:
11:14:33.951 [Start Level: Equinox Container: 6ee1939d-123f-4def-860f-dfc2e21bdfc4] WARN o.eclipse.jetty.webapp.WebAppContext - Failed startup of context o.e.j.w.WebAppContext#7c19344a{/my-learning-osgi-simple-rest-with-jetty-1.0-SNAPSHOT,file:///tmp/jetty-0.0.0.0-8081-my-learning-osgi-simple-rest-with-jetty-1.0-SNAPSHOT.jar-_my-learning-osgi-simple-rest-with-jetty-1.0-SNAPSHOT-any-9046322855444487913.dir/webapp/,UNAVAILABLE}{file:/home/prakash/mygit/my-learning-osgi-simple-rest-with-jetty/target/my-learning-osgi-simple-rest-with-jetty-0.1/plugins/my-learning-osgi-simple-rest-with-jetty-1.0-SNAPSHOT.jar}
javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:662)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:350)
at javax.naming.InitialContext.lookup(InitialContext.java:417)
at org.eclipse.jetty.plus.webapp.EnvConfiguration.createEnvContext(EnvConfiguration.java:258)
at org.eclipse.jetty.plus.webapp.EnvConfiguration.preConfigure(EnvConfiguration.java:67)
at org.eclipse.jetty.webapp.WebAppContext.preConfigure(WebAppContext.java:506)
at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:544)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.deploy.bindings.StandardStarter.processBinding(StandardStarter.java:46)
at org.eclipse.jetty.deploy.AppLifeCycle.runBindings(AppLifeCycle.java:192)
at org.eclipse.jetty.deploy.DeploymentManager.requestAppGoal(DeploymentManager.java:505)
at org.eclipse.jetty.deploy.DeploymentManager.addApp(DeploymentManager.java:151)
at org.eclipse.jetty.osgi.boot.BundleWebAppProvider.bundleAdded(BundleWebAppProvider.java:214)
at org.eclipse.jetty.osgi.boot.BundleWebAppProvider$WebAppTracker.addingBundle(BundleWebAppProvider.java:80)
at org.osgi.util.tracker.BundleTracker$Tracked.customizerAdding(BundleTracker.java:475)
at org.osgi.util.tracker.BundleTracker$Tracked.customizerAdding(BundleTracker.java:1)
at org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:256)
at org.osgi.util.tracker.AbstractTracked.track(AbstractTracked.java:229)
at org.osgi.util.tracker.BundleTracker$Tracked.bundleChanged(BundleTracker.java:450)
at org.eclipse.osgi.internal.framework.BundleContextImpl.dispatchEvent(BundleContextImpl.java:911)
at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:233)
at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:151)
at org.eclipse.osgi.internal.framework.EquinoxEventPublisher.publishBundleEventPrivileged(EquinoxEventPublisher.java:233)
at org.eclipse.osgi.internal.framework.EquinoxEventPublisher.publishBundleEvent(EquinoxEventPublisher.java:140)
at org.eclipse.osgi.internal.framework.EquinoxEventPublisher.publishBundleEvent(EquinoxEventPublisher.java:132)
at org.eclipse.osgi.internal.framework.EquinoxContainerAdaptor.publishModuleEvent(EquinoxContainerAdaptor.java:194)
at org.eclipse.osgi.container.Module.publishEvent(Module.java:483)
at org.eclipse.osgi.container.Module.start(Module.java:474)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.incStartLevel(ModuleContainer.java:1783)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.incStartLevel(ModuleContainer.java:1763)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.doContainerStartLevel(ModuleContainer.java:1725)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.dispatchEvent(ModuleContainer.java:1656)
at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.dispatchEvent(ModuleContainer.java:1)
at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:233)
at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:343)
____________________________
Welcome to Apache Felix Gogo
g!

How to register a provider in Jersey 1.x via ResourceConfig?

As com.sun.jersey.api.core.ResourceConfig doesn't contain 'register' method.
I want to register ContainerResponseFilter programmatically.
I also tried to register it via #Provider annotation:
#Provider
public class MyFilter implements ContainerRequestFilter, ContainerResponseFilter {
#Override
public ContainerRequest filter(ContainerRequest containerRequest) {
return containerRequest;
}
#Override
public ContainerResponse filter(ContainerRequest containerRequest, ContainerResponse containerResponse) {
return containerResponse;
}
}
But it's not triggered.
Update:
In web.xml:
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>rest.providers</param-value>
</init-param>
In server's log I see:
com.sun.jersey.api.core.ScanningResourceConfig init INFO: No
provider classes found.
Update2:
Added class:
public class MyApplication extends ResourceConfig{
public MyApplication(){
getProviderClasses().add(LoggingFilter.class);
}
constructor was not triggered.
In server Log I see:
Mar 28, 2018 3:46:47 PM com.sun.jersey.api.core.PackagesResourceConfig init
INFO: Scanning for root resource and provider classes in the packages:
rest.services
Mar 28, 2018 3:46:47 PM com.sun.jersey.api.core.ScanningResourceConfig logClasses
INFO: Root resource classes found:
class rest.services.RestRes1
Mar 28, 2018 3:46:47 PM com.sun.jersey.api.core.ScanningResourceConfig init
INFO: No provider classes found.
Mar 28, 2018 3:46:47 PM com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version 'Jersey: 1.9 09/02/2011 11:17 AM'
it only finds package with resources but not providers.
Update 3:
If I explicitly define my provider class in web.xml,
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
<param-value>rest.services.MyFilter</param-value>
</init-param>
It works fine.
But I need to do it programmatically.
You can use one of the following methods for registering providers in Jersey 1.x:
getProviderClasses(): Get the set of provider classes.
getProviderSingletons(): Get the set of provider singleton instances.
Alternatively you could use PackagesResourceConfig to scan and register the resource and provider classes from one or more packages:
#ApplicationPath("resources")
public class MyApplication extends PackagesResourceConfig {
public MyApplication() {
super("org.foo.rest;org.bar.rest");
}
}
Jersey offers a few deployment options according you environment. Check the documentation for details.

No log output on contextDestroyed using ServletContextListener & SLF4J

I am trying to write a message to the logger that a (Vaadin) servlet has stopped, this using SLF4J and Log4j2.
For this I am using a ServletContextListener which logs a message when the application has started. However I have been unable to get any output when logging inside the contextDestroyed method... Here is my implementation:
#WebListener
public class VaadinLogger implements ServletContextListener {
private static final Logger logger = LoggerFactory.getLogger(VaadinLogger.class);
#Override
public void contextInitialized(ServletContextEvent contextEvent) {
// Remove appenders from JUL loggers
SLF4JBridgeHandler.removeHandlersForRootLogger();
// Install bridge
SLF4JBridgeHandler.install();
// Get servlet context
ServletContext context = contextEvent.getServletContext();
// Retrieve name
String name = context.getServletContextName();
// Log servlet init information
logger.info("Start \"{}\"", name);
}
#Override
public void contextDestroyed(ServletContextEvent contextEvent) {
// Get servlet context
ServletContext context = contextEvent.getServletContext();
// Retrieve name
String name = context.getServletContextName();
// Log servlet destroy information
logger.info("End \"{}\"{}", name, System.lineSeparator()));
// Uninstall bridge
SLF4JBridgeHandler.uninstall();
}
}
At this point, I'm guessing this is probably because at the point contextDestroyed is called, logging is no longer possible because they have already been destroyed by the garbage collector.
So now my question is, is it possible to either log that the servlet has stopped before the context is destroyed, or make the contextlistener execute before log4j2 loggers are destroyed?
Thanks in advance!
Since log4j 2.14.1, you can disable the auto-shutdown and add a listener to stop the logger.
<context-param>
<!-- auto-shutdown stops log4j when the web fragment unloads, but that
is too early because it is before the listeners shut down. To
compensate, use a Log4jShutdownOnContextDestroyedListener and
register it before any other listeners which means it will shut
down *after* all other listeners. -->
<param-name>isLog4jAutoShutdownDisabled</param-name>
<param-value>true</param-value>
</context-param>
<listener>
<!-- ensure logging stops after other listeners by registering
the shutdown listener first -->
<listener-class>
org.apache.logging.log4j.web.Log4jShutdownOnContextDestroyedListener
</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
First, do you have the log4j 2.x api, core and web jars in your classpath? The log4j-web-2.x.jar also registers a context listener used to shut down the logging subsystem when the web app is unloaded.
If your listener runs after that you won't be able to log anything anymore.
You can check what's happening by setting <Configuration status="trace" ... in your log4j2 configuration file.
log4j2 (log4j-web-xx.jar) comes with a web-fragment. This fragment contains a ServletContextListener. The order of listeners are depend of the initialization (see Servlet Specification). Default: your application first then others.
Your can change the order to specify an <absolut-ordering> in your web.xml:
<web-app>
<absolute-ordering>
<name>log4j</name>
<others/>
</absolute-ordering>
See also: servlet-30-web-fragmentxml

Bean in DispatcherServlet accessing sibling bean

We have a web application with both a root application context (applicationContext.xml) and a dispatcher servlet (dispatcher-servlet.xml) defined in our web.xml like so:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext*.xml</param-value>
</context-param>
...
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
Due to the access restrictions, we obviously cannot access any of the DispatcherServlet beans from the root parent context.
But, what we'd like to be able to do is access the sibling beans. For example, in our dispatcher-servlet.xml we have:
<bean id="firstController" class="org.springframework.web.servlet.mvc.multiaction.MultiActionController">
...
</bean>
<bean id="secondController" class="org.springframework.web.servlet.mvc.multiaction.MultiActionController">
...
</bean>
How can we access the secondController from inside firstController, without requiring that it be passed in as a constructor-arg, or set as a property?
We're using WebApplicationContextUtils.getWebApplicationContext(...) to access siblings in the root applicationContext.xml, but we'd like to do the same thing in the child context. (From within one of the children.)
you can get an ApplicationContext object using
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("dispatcher-servlet.xml")
This is assuming dispatcher-servlet.xml is in class path. context object has to be cached.
Then use context.getBean() to access beans from any where.
Other option seems to be , use overloaded method where we can pass the context attribute name. I have not used it.
WebApplicationContextUtils.getWebApplicationContext(ServletContext sc, String attrName)

RESTEasy will not map my Spring bean with custom Spring ContextLoader

RESTEasy 2.0.1GA
Java 1.6
Spring 3.0.3
I have tried everything I can, and cannot make head or tail of what's going on. I have a Spring MVC application, however I'd like to have some RESTEasy endpoints available outside the Spring MVC app, but in the same container, ultimately being able to wire in the same beans.
As a first step, I'm simply trying to stand-up RESTEasy inside the container, serving requests from a Spring-configured bean. I have tried the boilerplate from the instructions and have also tried manual setup, to no avail.
Bean
#Resource
#Path("/")
public class NeighborComparison {
private String foo;
#GET #Path(value="customer") #Produces("text/plain")
public String getNeighborComparison() {
return "foo";
}
}
web.xml
<context-param>
<param-name>resteasy.servlet.mapping.prefix</param-name>
<param-value>/api</param-value>
</context-param>
<listener>
<listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
</listener>
<!-- NOT configuring SpringContextLoaderListener because I declare my own, so if I do, everything
blows up, plus all it actually does is sanity check configuration -->
<listener>
<listener-class>com.example.MyCustomContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>Resteasy</servlet-name>
<servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Resteasy</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
applicationContext.xml
<bean id="resteasy.providerFactory" class="org.jboss.resteasy.spi.ResteasyProviderFactory"
factory-method="getInstance">
</bean>
<bean id="resteasy.dispatcher" class="org.jboss.resteasy.core.SynchronousDispatcher">
<constructor-arg ref="resteasy.providerFactory"/>
</bean>
<bean id="resteasy.spring.bean.processor" class="org.jboss.resteasy.plugins.spring.SpringBeanProcessor">
<description>
Add Resources and #Providers to the appropriate places
in Resteasy's infrastructure
</description>
<constructor-arg ref="resteasy.dispatcher"/>
</bean>
<bean id="neighborComparison" class="opower.api.customer.neighbor_comparison.NeighborComparison">
</bean>
According to the documentation, all I have to do is “manually register the RESTeasy BeanFactoryPostProcessor by allocating an instance of org.jboss.resteasy.plugins.spring.SpringBeanProcessor”. I believe this spring configuration does that.
Jetty starts and the app context spins up with no issues. Application works normally, however when I
> curl -H"Accept: text/plain" localhost:8080/ei/api/customer
("ei" is the application context). The log shows (this and only this):
2011-03-29 16:44:24,153 DEBUG [qtp-575315405-0] [EI] [] [asy.core.SynchronousDispatcher] PathInfo: /customer
2011-03-29 16:44:24,156 DEBUG [qtp-575315405-0] [EI] [] [asy.core.SynchronousDispatcher] Failed executing GET /customer
org.jboss.resteasy.spi.NotFoundException: Could not find resource for relative : /customer of full path: http://localhost:8080/ei/api/customer
Even if I could convince RESTEasy to show me the mappings, it seems that it's just not discovering my bean.
If I map it explicitly via the resteasy.resources context param, it works, though obviously doesn't have access to auto-wired Spring beans.
Anything else I can try? I have debug log on the entire RESTEasy codebase and I don't get any messages. I've also confirmed that Spring is, in fact, creating my bean, so it's just that RESTEasy isn't finding it.
Your resource class needs to be annotated with #Path annotation for RESTeasy to pick up on it during bootstrap:
#Path("/customer")
#Resource
public class NeighborComparison {
#GET #Path("/{customerId}") #Produces("text/plain")
public String getNeighborComparison(#PathParam("customerId") long customerId) {
return "foo";
}
}
Note the #Path("/{customerId}} annotation without which your #PathParam parameter would not have been mapped correctly, resulting in a pretty detailed exception (and an accompanying 500 response on the client side). Assuming the service is picked up by RESTeasy of course.
In addition if you don't use RESTeasy's SpringContextLoader, you have to make sure your SpringBeanProcessor instance is registered with the ApplicationContext. RESTeasy delegates to it by registering an ApplicationListener in SpringContextLoader:
ApplicationListener listener = new ApplicationListener() {
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ContextRefreshedEvent) {
ContextRefreshedEvent cre = (ContextRefreshedEvent) event;
ConfigurableListableBeanFactory autowireCapableBeanFactory = (ConfigurableListableBeanFactory) cre
.getApplicationContext().getAutowireCapableBeanFactory();
new SpringBeanProcessor(dispatcher, registry, providerFactory)
.postProcessBeanFactory(autowireCapableBeanFactory);
}
}
};
configurableWebApplicationContext.addApplicationListener(listener);
If using a custom context loader and not the RESTEasy-provided one, this code has to appear somewhere in your context loader so that everything gets wired up. A bit convoluted, yeah. It is SpringBeanProcessor that goes through all Spring beans and registers with RESTeasy those that have a #Path annotation somewhere in their hierarchy (type and their corresponding interfaces).

Categories