How to get OSGi service links from a servlet registered with OSGi HttpService?

It seems natural that an HttpServlet running on an OSGi environment (i.e. registered with OSGi HttpService ) would like to call some OSGi services to perform its tasks. The question is how to get links to this OSGi service inside the servlet.

One way is to embed the dependencies in the HttpServlet instance, which is registered with the OSGi HttpService as follows:

MyServlet servlet = new MyServlet(); servlet.setFooService(fooService); httpService.registerServlet("/myservlet", servlet, initparams, context); 

I'm not sure if this is a valid approach, since in a non-OSGi environment, the servlet life cycle is managed by the web container and therefore no service reference will be entered for servlet instances created later.

There is another way to solve this problem when using PAX Web as an implementation of OSGi HttpService. PAX Web exports the OSGi BundleContext to ServletContext as the osgi-bundlecontext special attribute. Then the BundleContext can be used to get the necessary service links:

 public void init(ServletConfig servletConfig) throws ServletException { ServletContext context = servletConfig.getServletContext() BundleContext bundleContext = (BundleContext) context.getAttribute("osgi-bundlecontext"); ServiceReference serviceRef = bundleContext.getServiceReference("com.foo.FooService") } 

However, this approach is pretty ugly and connects you with a specific OSGi HttpService implementation. Do you know any other (and possibly better) solution to this problem?

+4
source share
3 answers

If you use the installer to depend on the service, as you have shown, it can work outside of OSGi. You just need to use some other dependency injection mechanism. If not, you can provide a subclass that initializes the servlet using JNDI lookup or from the servlet context.

 public class MyServlet_AdapterForMissingDI extends MyServlet{ public void init(ServletConfig config){ setFooService(getItFromSomewhere()); } } 

The thing is, if you have DI capabilities that can setFooService can embed, you can just use the same servlet in OSGi and in other places, if you haven’t (and still want to support this case), you provide an adapter.

Check the Felix SCR in the corresponding note to configure dependencies between objects and the Pax Web Extender board, which will take care of connecting your servlet to the HttpService.

In particular, without SCR and Whiteboard, you need to think about the case when fooService becomes unavailable later, or HttpService starts after your servlet. In these cases, your servlet will refer to a dead service that prevents garbage collection, or your servlet will not be registered with the HttpService.

Update: Here is the SCR handle that I use for one of my servlets. SCR handles the servlet instance, life cycle, registration (through the board), and dependencies. There is no OSGi code in the servlet. There is no longer a need for a BundleActivator (SCR registers all services):

 <component name="oracle.statusServlet" > <implementation class="mypackage.DataSourceStatusServlet"/> <property name="service.description" value="Oracle DataSource status servlet" /> <property name="alias" value="/OracleDataSourceStatus" /> <property name="servlet-name" value="Oracle DataSource status servlet" /> <service> <provide interface="javax.servlet.Servlet" /> </service> <reference name="DATASOURCES" interface="javax.sql.DataSource" cardinality="0..n" policy="dynamic" bind="bindDataSource" unbind="unbindDataSource"/> </component> 

Dependencies for the servlet are specified in the reference tag. SCR will search and bind the service.

+2
source

Maybe an old post, and you already have an answer. You start felix or some OSGi container yourself. If so, you can set the bundle context as an attribute of the servlet context.

Incorrect use of the PAX http service. ultimately, flow control and other aspects are performed by the servlet container where you run this http service.

+2
source

You can inject services into some object, which is then requested by servlets.

-1
source

Source: https://habr.com/ru/post/1286307/


All Articles