Search code examples
javaarchitecturejettyembedded-jettyapache-felix

What is the appropriate embedding mechanism for jetty, felix, bundles and webapps


After looking for a long time without finding a good answer, I come to the place where good answers are found.

I'm creating en ecosystem of independent applications (modeled as a WebApp in a WAR) and service modules (plugins) that those WebApps can consume (modeled as an OSGI bundle). I'm having trouble getting my head around how to architect those elements with Apache Felix and Jetty. The way I understand it I have three possible ways of doing it, but I have no idea of the implication of each.

  1. Create a felix container that brings up the plugins, and also brings jetty who eventually bring up the WebApps.

  2. Create a jetty server with embedded felix to provide the plugins, and use Jetty's deployer to manage the WebApps.

  3. Create a jetty server with a less complicated framework than OSGI to manage the plugins, and use Jetty's deployer to manage the WebApps.

Option 1 seems to be a very orthogonal solution, everything is an osgi module (assuming the wars are a module), and managing the whole thing would be just a matter of creating the felix infrastructure and bringing everything up. From my early testing, managing all these osgi modules in development is not an easy or fast task (but most likely I'm doing something wrong).

Option 2 seems that it would work (is the one that I have managed to get further from the two) and is simpler to manage my head around, since the OSGI is limited to managing only the plugin infrastructure and not the applications or the server.

Option 3 I haven't even started to explore.

I'm expecting to have several independent applications (WebApps) and many many plugins (OSGI modules) and I would like to hear from you on the pros and cons of each option, in terms of maintainability and ease of development.


Solution

  • One of the problems here is that 1 and 2 are both valid use cases of osgi frameworks.

    I would recommend having a detailed look at JBoss Fuse, as this is a very mature implementation of option 1 (ignoring the container based, openshift stuff and focus on the on prem version). The basics of it are:

    • a single JVM that hosts an OSGI container based on Apache Felix. (It's really Apache Camel, repackaged from Apache Servicemix, which uses Apache Karaf, which can either use felix or the Eclipse OSGi framework. Turtles all the way down).
    • Applications are packaged as osgi bundles that can include a servlet engine.
    • The servlet engine can then also utilise osgi to run a plugin / framework system.

    You will probably not be surprised at the huge amount of house of cards tooling it requires to get this stuff up and running, and then maintaining it. You wont suffer from classpath dependency clashes, but the cost is an extremely complicated toolchain for creating and deploying bundles. This also makes unit and component testing very difficult. Some of this is just due to how complex fuse is, but trying to seperate the unnecessary complexity from the necessary is a hard problem.

    A hello world on Fuse, where you are digging into each part of the platform and really getting to know what's happening, would probably take a week.

    Leaving fuse aside, there are plenty of issues with either option 1 or 2

    • you are still limited by the JVM and its threads. You need to take some care to ensure everything works together as it is very easy for a single bundle or plugin to happily consume the entire CPU and block other applications from doing work.
    • plugins have a lifecycle that needs to be managed - start, stop, load, reload, unload. There are a number of management issues that will bite right away - How do you force stop a plugin? When do you give up and restart the JVM?
    • who is writing the plugins, where are they hosted or built, how do you trust them and so on.

    OSGi is pretty successful client side, but IMHO the reason there's not many really well known server side OSGi implementations is because it's really difficult to manage with lots of threads and unpredictable request flow and people just don't get the results they want - run code from different sources in varying configurations, as decided by a user - from the pain of making it work.

    So are there any other mature plugin frameworks that solve these issues in a simple reliable way? Not that I'm aware of! There's plenty around on github and google, but they always end up foundering on the same rocks of coming up with a reliable way of managing the plugins and making them play nice with the other things running in the JVM.

    I would much prefer to keep the independent applications independent via their own docker container and then maybe look at felix if you really need to be able to load plugins at runtime.