Extending Java Web Applications with Plugins

I have this web application that has grown into an uncontrollable mess.

I want to break it down into the general part of the "framework" (which still includes web material such as pages and images) and several modules that add additional functionality and screens. I want this refactoring to be useful as a plugin for third-party extensions.

All modules should be a separate deployment unit, ideally a war or flag file.

I tried to just make some regular war files, but Tomcat (according to the servlet specification) stores these war files completely separate from each other, so that they cannot share their classes, for example.

I need plugins to see the “main” class path.

I need the main application to have some control over the plugins, for example, the ability to list them and set their configuration.

I would like to maintain a complete separation between the plugins themselves (if they do not specify dependencies) and any other unrelated web applications that can run on the same Tomcat.

I would like them to be embedded in the main application URL prefix, but this is not necessary.

I would like to use Tomcat (big architectural changes need to be coordinated with too many people), but also hear about a clean solution in the EJB or OSGi world, if any.

+6
java tomcat servlets modularity
source share
8 answers

I worked on the idea of ​​using OSGi to solve the same problem that you are describing. In particular, I am considering using Spring Dynamic Modules .

+4
source share

Take a look at the Java portlets - http://developers.sun.com/portalserver/reference/techart/jsr168/ - in a nutshell, a specification that allows you to interact between what is otherwise a self-contained j2ee web application

Edit I forgot to mention that portlets are largely not agnostic, so you can use Spring as a parent application, and individual developers can use whatever they want in their portlets.

+3
source share

Have you looked at using maven to highlight your projects, and then have they resolved the dependencies between WAR and JAR? You will end up duplicating libraries between WARs, but only where necessary (and this should not be a problem if you do not enjoy the funky classloader).

Tomcat also allows you to configure cross-context applications if you need to get from one WAR to another in a relatively transparent way ...

If you want to keep things under the same one web application (say, ROOT), can you create a proxy server that forwards to another other website behind the scenes so that the user makes it relatively transparent?

+1
source share

Your main problem will be centered around the physical, static assets of the system - the rest is simple, efficient, banks.

WARs are shared in Tomcat with separate class loaders, but they are also shared at the session level (each WAR is an independent web application and has its own session state).

In Glassfish, if WARs were merged into an EAR, they would separate the class loaders (GF uses the flat space of the class loader in the EAR), but will still have a separate session state.

Also, I'm not sure if you can "forward" another WAR to the server. The problem is that forwards use the relative URL of the root of the web application, and each WebApp has its own root, so you just can't get there. You can redirect, but this is not the same as redirecting.

Thus, these features of the web application are plotting against you, trying to lay them out uniformly inside the container.

Rather, I think the hint of advice is to create an “assembler” utility that takes your individual modules and “merges” them into one web application. It can combine its web.xml, their contents, normalize banks and classes, etc.

WAR is a function and a bug in the Java world. I love them because they really do deploy the compiled Drag and Drop applications in terms of installing them, and this feature is used much more than what you come across. But I feel your pain We have a common “core” structure that we use in different applications, and we basically need to constantly combine it in order to support it. We prepared the script, but it's still a bit of a pain.

+1
source share

“Also, I'm not sure you can“ redirect ”another WAR to the server. The problem is that the forwards use the relative URL of the web application root, and each WebApp has its own root, so you just don’t can get there from here. "You can redirect, but it's not the same as forward."

You can forward another WAR as long as this WAR allows someone to do so.

glass fish and several WAR EAR: it makes sense.

If you put the MAIN classes in a common CLASSPATH from tomcat, you can put your individual PLUGINs in separate WAR files.

The main application can also be part of the TOMCAT servlet, which you define in server.xml. It can be a MASTER SERVLET, and all other WARs can be managed by this master servlet.

It makes sense?

BR,
~ A

+1
source share

Depending on the complexity of the functionality of the plugin, I also consider a web service, for example, implemented using Axis.

Then your main application is configured with the URL of the web application (plugin) that provides the service.

The advantage, as I see it, is twofold:

  • You get a nice, clean, debugged API between two wars, namely: Soap / XML Messages
  • You can upgrade one plugin without the need for regression testing of the entire application

It is depressing that you need to set up some Axis projects, and that you must have some kind of plugin configuration. In addition, you may need to restrict access to application services websites, so some configuration may be required.

If the plugins work in the same database, be sure to limit the cache time or adjust the scope of the war cache layer.

0
source share

I am also trying to develop a general or abstract structure where I can add plugins (or modules) at runtime and improve existing running webapps.

Now, as you said, the preferred way to do this is with a WAR or JAR file. The problem with the WAR file is that you cannot deploy it as a plugin for an existing application. Tomcat will deploy it as a separate web context. Undesirable.

Another option is a JAR file and writing some code to copy this JAR file to the WEB-INF / lib folder and load the classes into an existing class loader. The problem is how to deploy non-java files like JSP or configuration files. There are two solutions for this: a. Use speed patterns instead of JSP (b.), Write some custom code to read the JSP from the class path instead of the context path.

OSGI or Spring Dynamic Modules are good, but at this time they look too complicated for me. I will consider it again if I feel it.

I am looking for a simple API that can take care of the life cycle of a plugin and is still able to use the JSP in my packed JAR file.

Perhaps you can use the un jar plugin during deployment and copy the files to the correct directories.

0
source share

Actually nothing is better than OSGI if you are thinking about dividing the application into separate modules. Take a look at the Greenpages example. You can create a parent module (kernel) where you include the banks that your application needs.

If you know something about component programming, you'll soon find out that OSGI modules behave like interfaces, where you need to expose what you will use in other modules. It is quite simple as soon as you understand. In any case, it can also be very painful when you learn how to use OSGI. We had problems using JSON, because the version of Jackson that we added as a jar to the module was overridden by another jar that was contained in the main Spring modules. You always need to double check which version of the jar is loaded for your needs.

Unfortunately, even the OSGI approach does not decide what we are looking for. How to extend a constant model and existing forms at runtime.

0
source share

All Articles