3
votes

I've searched a long before posting this question, without finding a satisfying answer, as premise I want say that I would prefer don't using frameworks to do the following task, the only tools I have are Felix, Jetty and a Webapp.

I have a webapp managed with maven which I deploy in jetty outside OSGI env, but now I would like to deploy it in OSGI too, so I'm facing up to with typical OSGI matters and principles, here follows what I understood, please let me know if I'm going wrong:

  • I can leave maven "war" packaging

  • With apache.felix maven-bundle-plugin I create OSGI MANIFEST

  • In OSGI there should be the jetty-bundle started before any "webapp bundle"

  • The webapp bundle will have its WEB-INF/classes but, to be really OSGI style it will not have any WEB-INF/lib since it will find its dependencies as OSGI bundles elsewhere

    I thank you if you want to add elements, unfortunately I found only articles to quickly transform a standard war in a bundle, but I'm really interested to work in respects of OSGI principles, so I would prefer to be as compliant as possible

1

1 Answers

3
votes

Firstly, to answer your higher level OSGi questions:

  • I can leave maven "war" packaging

Yes, but this then means that you are producing a WAR file, with all the rules that follow. You may therefore end up fighting the maven-war-plugin at some point.

  • With apache.felix maven-bundle-plugin I create OSGI MANIFEST

I prefer using the bnd-maven-plugin, but both use the same library (bnd) under the covers. Generating the OSGi manifest (rather than writing it by hand) is a very important step toward success.

  • In OSGI there should be the jetty-bundle started before any "webapp bundle"

In a well written OSGi system there should be absolutely no start up ordering restrictions. Your web application will not be available until Jetty has started, but it should not matter which bundle starts first.

The webapp bundle will have its WEB-INF/classes but, to be really OSGI style it will not have any WEB-INF/lib since it will find its dependencies as OSGI bundles elsewhere

This is up to you. Obviously to remain a valid WAR file the classes must be in WEB-INF/classes. OSGi can cope with this (although you need to set the Bundle-Classpath) but it is not required. If you want to put them in / then go ahead. Embedded JARs are also supported by OSGi, but again, not required. Using / as the class path and referencing libraries using Import-Package is a much more idiomatic use of OSGi.

Servlets in OSGi

There is an OSGi specification which supports web applications. It's called the Web Applications Specification and it is chapter 128 of the OSGi compendium specification. This is one of the ways in which you can publish servlets from inside an OSGi container. There are, however, other ways to use Servlets in OSGi.

If you want to just do everything using a WAR file then skip ahead, as I am about to tell you an alternative, which you may find easier/better.

How to deploy Servlets in OSGi

The best and easiest way to deploy servlets in OSGi is to use the Http Whiteboard (OSGi compendium chapter 140). Registering a servlet is really simple, you simply publish it as an OSGi service with the patterns it should match. For example, when using Declarative Services:

@Component(property="osgi.http.whiteboard.servlet.pattern=/foo")
public class MyServlet extends HttpServlet implements Servlet {
    ...
}

You can also register Filters, Listeners and all sorts of other things. Using Declarative Services like this makes it very easy to interact with other OSGi bundles by injecting services that they provide.

The Apache Felix Http Service is nice, easy to use implementation of this specification which is based on Jetty.

How to deploy a Web Application Bundle

If you really want to deploy as a Web Application Bundle then there are a few things to be aware of.

Edited as per request from the original submitter

  1. The lifecycle of all your servlets is exactly the same as the lifecycle of your bundle, so it's hard to use OSGi services properly. Inside a Web Application Bundle you get no ability to limit the visibility of a servlet if a service it depends on is missing or becomes unavailable. This can lead to you relying on bundle start order, which sucks!
  2. You have to set extra metadata in your OSGi manifest to ensure that OSGi can cope with the WAR layout, and recognise your bundle for processing.
    • Bundle-ClassPath: WEB-INF/classes[, WEB-INF/lib/foo.jar]
    • Web-ContextPath:
  3. Jetty is not (to my knowledge) an implementation of the OSGi Web Applications Specification. You will need an implementation (which could be running on top of Jetty), for example PAX-Web.
  4. The OSGi Web Applications specification only defines support for Servlet 2.5 (anything higher is implementation value add).
  5. Many people view Web Application bundles as a migration path, rather than an end goal. Having a peculiar internal layout (WEB-INF/classes) and typically following a "fat jar" model means that web application bundles often have limited modularity and can be hard to use with other tools. Also their inability to interact well with OSGi services (see point 1) makes them harder to write/maintain than more modular patterns such as the OSGi Http Service Whiteboard. This means some (myself included) see a Web Application bundle as a "first step" in migrating to OSGi, eventually using the Http Service Whiteboard.

Depending on the way that your maven build is set up you may find that it is necessary to use the -wab instruction for bnd. This gets bnd to put your classes into WEB-INF/classes and to set up the Bundle-ClassPath