OSGi & Servlets: A Happy Marriage
Join the DZone community and get the full member experience.
Join For Freein this post, i'll show you how to create a simple osgi-based servlet. later, we will deploy this servlet to an amazon ec 2 instance - this should be fun!
first of all , some preliminary steps. we need to create a new osgi project and add some dependencies:
- create a new plug-in project, naming it simple.servlet . make sure to select equinox as the target osgi framework on the first page of the wizard. also make sure you've got an activator (that option is on by default).
-
open the manifest editor and add the
following packages to the
imported packages section on the dependencies tab:
- javax.servlet
- javax.servlet.http
- org.osgi.framework
- org.osgi.service.http
- org.osgi.util.tracker
next , let's create the servlet. servlets are plain java classes that implement the javax.servlet.servlet interface. as we want to serve information over http, we can just create a subclass of javax.servlet.http.httpservlet which already does some of the heavy lifting for us. all we need to do is override the doget() method. this method does not have a return value. instead, we need to fill its second parameter, httpservletresponse resp with the text we want the web browser to display. we could return html, but for simplicity's sake, let's just return plain text (so make sure to set the content type to text/plain):
package simple.servlet;
import java.io.ioexception;
import javax.servlet.servletexception;
import javax.servlet.http.httpservlet;
import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletresponse;
public class simpleservlet extends httpservlet {
private static final long serialversionuid = 1l;
protected void doget(httpservletrequest req, httpservletresponse resp)
throws servletexception, ioexception {
resp.setcontenttype("text/plain");
resp.getwriter().write("hello from the cloud!");
}
}
in order for the servlet to be accessible via http, we need to register it. if you have done some jee/j2ee development, you know that servlets are registered using the web.xml servlet descriptor. as we're not in the jee world any longer, we can't go down this road. instead, we will register the servlet using a org.osgi.util.tracker.servicetracker. it's a little bit more code to write, but let me tell you: it's worth it as you'll see very soon.
the service tracker will be registered for a specific class - in our case that's org.osgi.service.http.httpservice:
package simple.servlet;
import org.osgi.framework.bundlecontext;
import org.osgi.framework.servicereference;
import org.osgi.service.http.httpservice;
import org.osgi.util.tracker.servicetracker;
public class httpservicetracker extends servicetracker {
public httpservicetracker(bundlecontext context) {
super(context, httpservice.class.getname(), null);
}
// ...
when the service tracker is asked to return the httpservice, we can register our servlet:
/ ...
public object addingservice(servicereference reference) {
httpservice httpservice = (httpservice) super.addingservice(reference);
if (httpservice == null)
return null;
try {
system.out.println("registering servlet at /simple");
httpservice.registerservlet("/simple", new simpleservlet(), null, null);
} catch (exception e) {
e.printstacktrace();
}
return httpservice;
}
/...
likewise, we must make sure to unregister the servlet when the service tracker is asked to shut down the httpservice
// ..
public void removedservice(servicereference reference, object service) {
httpservice httpservice = (httpservice) service;
system.out.println("unregistering /simple");
httpservice.unregister("/simple");
super.removedservice(reference, service);
}
}
now that we've got the servlet in place, we need to make sure the service tracker is started and stopped when our bundle is started and stopped. those of you familiar with osgi know where we're heading now: we need to implement the start() and stop() methods of our activator:
package simple.servlet;
import org.osgi.framework.bundleactivator;
import org.osgi.framework.bundlecontext;
public class activator implements bundleactivator {
private httpservicetracker servicetracker;
public void start(bundlecontext context) throws exception {
servicetracker = new httpservicetracker(context);
servicetracker.open();
}
public void stop(bundlecontext context) throws exception {
servicetracker.close();
servicetracker = null;
}
to test your servlet locally , create a new launch config:
- in the main menu, select run -> run configurations...
- double click on osgi framework in the tree on the left hand side to create a new osgi-based launch config
-
make sure you select the following
eight
(8)
bundles on the
bundles
tab:
- simple.servlet
- javax.servlet
- org.eclipse.equinox.http.jetty
- org.eclipse.equinox.http.servlet
- org.eclispe.osgi
- org.eclispe.osgi.services
- org.mortbay.jetty.server
- org.mortbay.jetty.util
- head over to the arguments tab, making sure the vm arguments text box reads -declipse.ignoreapp=true -dosgi.noshutdown=true -dorg.osgi.service.http.port=8080
and name it simple servlet (osgi)
you can now start the server by executing the launch config. after a very short time, the text registering servlet at /simple should appear in the console window, indicating your osgi-based server and your servlet have been started up (a lot faster that it would have taken on tomcat or any other jee server, for that matter).
open your web browser at http://localhost:8080/simple to observe your servlet in action:
congratulations , you've just built your first osgi-enabled servlet. in the next post, i'll show you how to deploy this servlet in an amazon ec2 instance. you can download the source code for this post from my svn repository on google code.
from
http://www.peterfriese.de/osgi-servlets-a-happy-marriage
Opinions expressed by DZone contributors are their own.
Comments