Which framework may I use for plugin handling in a web-app

69 views Asked by At

I would like to develop a java web app (eg: spring-mvc) with a left menu containing "groups", each group as a set of links available to open whatever functionality represents.

I would like each "group" to be independetly deployable with a jar approach, so it would be something like:

  • I put a new jar in the plugins folder
  • The web app automatically detects the plugin
  • A new group is automatically shown at the left menu
  • Clicking any link of the new group calls the controller included in the new jar and elements are displayed at the center div of the app

My question is: Is there already any framework to manage the plugin detection / registration ?

I've read that OSGi could be a solution to approach this architecture, but I am not sure if this is the right choice for what I need.

2

There are 2 answers

0
kapex On BEST ANSWER

I don't know any specific frameworks that support your requirements but I can think of two approaches how you can implement it on your own or integrate it in existing web frameworks.

OSGI:

The Apache Felix FileInstall module can automatically install and start OSGi bundles that are dropped into monitored directories. In theory, with the right server and http support modules, you can drop in your webapp bundle jar files and the OSGi container will deploy them and route all requests to the paths specified in the webapps web.xml file to your plugin.

In practice you have to learn a lot about OSGi beforehand and possible experiment a lot with different implementations of the OSGi specifications. OSGi sounds good for the features you want and certainly can do the job well, but it might be overkill if your project is small.

SPI:

If you want to go for something (much) simpler, take a look at the SPI (Service Provider Interface) API. You need to implement most features by hand with SPI though. There is no plugin lifecycle like in OSGi, but that's ok if you only want to deploy and don't plan to undeploy. You need to implement dynamic loading of jars yourself, for example like described in this question.

I don't know about Spring MVC, but you should actually be able to integrate this approach any web framework that supports dynamic addition of pages after the framework has been started. The main application would need to register all installed webapp services in the web framework and add them in the menu group. The webapps could load the site layout, menu, assets etc. from the main application and add their own content and functionality, preferably using some DI framework for all of this.

0
Aaron Digulla On

While this might be possible to do in Java alone, you'll pay for it with the usual problems (unstable/slow deployment, huge application, managing conflicting dependencies of your plugins).

A better approach is:

  • Create an application where other applications can register. Let's call this one "core". Core knows which "groups" exist.
  • For each group, deploy an independent application. When they start, they can register themselves in core using simple web requests (look at REST). When they go down, they can unregister themselves. Core should ping them from time to time to find dead ones.
  • When a creating the HTML for links, you have two options: Either let core render links that go directly to the plugins or make core a kind of proxy which receives all events and forwards them. The first one can be hard to get right because of the same origin policy.

The advantages of this approach are:

  • Each plugin is truly independent of the core. If one plugin needs JAR Foo in version 3 and and another one needs version 4? No problem.
  • If one or more plugins die, the rest of the functionality is still available
  • You will be able to test each plugin independently of the rest.
  • using a REST/JSON interface between the plugins will make them easy to change. With AJAX, you can use those interfaces directly from the browser.

Drawbacks:

  • You need to send messages between the plugins if they need to access each other. Simple method calls aren't possible.