Table of contents
OSGI
manifest
minimal manifest:
Bundle-SymbolicName: bundlename
activator
Bundle-Activator: com.example.Activator
import export
Import-Package: org.osgi.framework, java.swing
Export-Package: com.example.foo, com.example.bar
optional osgi entries:
Bundle-Name: human readable name
Bundle-Version: 1.0.0
Bundle-Description: description of bundle
Bundle-Category: optional
Bundle-Vendor: Management Porno ltd.
Bundle-ContactAddress: E.T. phone home
Bundle-Copyright: something something licence
Bundle-DocURL: http://www.example.com/optional/documentation/link
OSGI code samples
Hello World bundle
manifest.mf (minimal):
Bundle-SymbolicName: HelloWorld
Bundle-Activator: Activator
Import-Package: org.osgi.framework
hello world class:
import org.osgi.framework.*;
public class Activator implements BundleActivator {
public void start(BundleContext context) {
System.out.println("Hello!");
}
public void stop(BundleContext context) {
System.out.println("Goodbye!");
}
}
manual packaging
javac -classpath /path/to/felix.jar Activator.java
jar -cfm HelloWorld.jar manifest.mf Activator.class
services
publishing a service
ServiceRegistration<Runnable> registration;
registration = context.registerService(Runnable.class, () -> System.out.println("osgi service"), null);
consuming a service
ServiceTracker<Runnable, Runnable> tracker = new ServiceTracker<>(context, Runnable.class, null);
tracker.open();
Runnable service = tracker.getService();
if (service != null) {
service.run();
}
adding a service listener
context.addServiceListener(new ServiceListener() {
@Override
public void serviceChanged(ServiceEvent event) {
Map<Integer, String> types = new Hashtable<>();
types.put(ServiceEvent.REGISTERED, "REGISTERED");
types.put(ServiceEvent.UNREGISTERING, "UNREGISTERING");
types.put(ServiceEvent.MODIFIED, "MODIFIED");
types.put(ServiceEvent.MODIFIED_ENDMATCH, "MODIFIED_ENDMATCH");
String type = types.get(event.getType());
System.out.println("service " + type + " detected " + event);
}
});
listening for services implementing a specified interface
String filter = "(objectclass=" + MyInterface.class.getName() + ")";
context.addServiceListener(listener, filter);
removing the listener (on stop activator)
context.removeServiceListener(listener);
Shutdown OSGI
try {
Framework systemBundle = context.getBundle(0).adapt(Framework.class);
systemBundle.stop();
System.out.println("Waiting up to 2s for OSGi shutdown to complete...");
systemBundle.waitForStop(2000);
} catch (Exception e) {
System.err.println("Failed to cleanly shutdown OSGi Framework: " + e.getMessage());
e.printStackTrace();
}
registering a HTTP Servlet
import java.util.Hashtable;
import javax.servlet.Servlet;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.http.whiteboard.HttpWhiteboardConstants;
public class Activator implements BundleActivator {
private ServiceRegistration<Servlet> registration;
@Override
public void start(BundleContext context) throws Exception {
Hashtable<String, String> props = new Hashtable<>();
props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/*");
registration = context.registerService(Servlet.class, new HelloWorldServlet(), props);
}
@Override
public void stop(BundleContext context) throws Exception {
registration.unregister();
}
}
HelloWorldServlet
import java.io.IOException;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloWorldServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().println("hello: " + new Date());
resp.getWriter().close();
}
}
on felix: requires the HTTP API and HTTP jetty bundles
Registering a servlet Filter
import java.util.Hashtable;
import javax.servlet.Filter;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.http.whiteboard.HttpWhiteboardConstants;
public class Activator implements BundleActivator {
private ServiceRegistration<Filter> filter;
@Override
public void start(BundleContext context) throws Exception {
Hashtable<String, String> props = new Hashtable<>();
props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_PATTERN, "/*");
filter = context.registerService(Filter.class, new HelloWorldServletFilter(), props);
}
@Override
public void stop(BundleContext context) throws Exception {
filter.unregister();
}
}
HelloWorldFilter
import java.io.IOException;
import java.util.Date;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class HelloWorldServletFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("FILTER INIT");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
response.getOutputStream().print("FILTER: " + new Date());
response.getOutputStream().close();
}
@Override
public void destroy() {
System.out.println("FILTER EXIT");
}
}
note: Filters are called only for url's backed by a content provider (servlet) and cannot be used as a catch all.
configuration
HTTP_WHITEBOARD_FILTER_PATTERN follows the Java Servlet specification
props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_PATTERN, "/*");
use "/.../*" for path mapping
use "*.[ext]" for extension mapping
use "/" for the default servlet
all other strings are exact matches
use HTTP_WHITEBOARD_FILTER_REGEX instead (mutually exclusive) for more fine grained control
props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_REGEX, "^/.*/[1-3].*+$");
documentation
https://docs.osgi.org/specification/osgi.cmpn/7.0.0/service.http.whiteboard.html
Further reading
eclipse OSGI support
http://www.vogella.com/tutorials/OSGi/article.html
OSGI specification on HTTP whiteboard
https://osgi.org/specification/osgi.cmpn/7.0.0/service.http.whiteboard.html