Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add a feature of modularity to a Java web application

I have developed a Java EE based web application as an Open Source Project.

Now some contributors like to add additional functionality through modules plugged into the web application.

Can you please explain how to achieve that or direct me to a source reference.

like image 329
Buddhika Ariyaratne Avatar asked Jul 20 '19 10:07

Buddhika Ariyaratne


2 Answers

I would say that OSGi is something you should consider. I don't have expertise in the area but you can find examples and descriptions in stackoverflow and other online resources.

What does OSGi solve?

Trouble understanding the whole OSGi web eco system

The Introduction to OSGi tutorial uses Apache Felix and Apache Karaf and gives a seemingly straightforward tutorial on creating service bundles. From the tutorial:

The Open Service Gateway Initiative is a specification defining a Java-based component system. It’s currently managed by the OSGi Alliance, and its first version dates back to 1999. Since then, it has proved to be a great standard for component systems, and it’s widely used nowadays. The Eclipse IDE, for instance, is an OSGi-based application.

A seemingly more sophisticated tutorial could be OSGi Modularity - Tutorial

The ServiceLoader provides A simple service-provider loading facility. but looks way to simplified for your needs. It works will for spring-boot but it does not seem to be meant to enterprise applications. A simple example of it is like this:

The Framework of your application:

public class FrameworkClass {    
    public static void main(String[] args) {
        new FrameworkClass().run();
    }
    private void run() {
        ServiceLoader<IFrameworkModule> modules = ServiceLoader.load(IFrameworkModule.class);
        modules.forEach(IFrameworkModule::initialize);
        modules.forEach(IFrameworkModule::execute);
    }
}

An interface that service modules implement:

public interface IFrameworkModule {
    public void initialize();
    public void execute();
}

A module - in a separate jar - for the application

public class Module1 implements IFrameworkModule {
    @Override
    public void initialize() {
        System.out.println("initialize module1");
    }

    @Override
    public void execute() {
        System.out.println("execute module1");
    }
}

which needs a framework.IFrameworkModule file in the META-INF/services folder

fmodule.Module1

But considering the complexity of your application I think it makes more sense to go with OSGi.

like image 164
K.Nicholas Avatar answered Oct 21 '22 17:10

K.Nicholas


I had a similar task with my project ioc-unit. I wanted the user to add the capability to test Mockito-objects, Rest-Services or Ejb-Services independent from the basic algorithm and include only those capabilities which are necessary.

The principles I used are defined in service-provider-interface by oracle(java).

Therefore I defined a service-interface which is implemented and defined in META-INF/services by the modules which should be added in a flexible way. Example for that: ioc-unit-resteasy for testing rest-webservices or ioc-unit-mockseasy to introduce mockito mocks inside cdi-tests.

Then the current configuration is recognized using config-finder. This finder will be able to call all interfaces of all modules (jars) which are included in your deployable. In the ioc-unit-case the analyzer uses the interface to interpret the found classes in a special way. If ioc-unit-ejb is included, then Ejb-Annotations are recognized, if ioc-unit-mockeasy, @Mock is recognized, if ioc-unit-resteasy: @Path and @Provider.....

like image 22
aschoerk Avatar answered Oct 21 '22 18:10

aschoerk