Building a Plugin Based Architecture in Scala

A plugin based architecture has many advantages. Some of the common ones include

  • Extending an application’s functionality without compiling it again
  • Adding functionality without requiring access to the original source code.
  • Replacing or adding new functionality becomes easy
  • Help in organizing large projects
  • Help in extending the functionality of the system to unimagined areas. I know this one sounds extreme but believe me it is true. For our framework, plugins were written by third-party library providers whose domain ranged from health-care to natural language processing.

The major components of our plugin system are the following

  1. Plugin trait – Which all the plugins would extend
  2. PluginManager Object – Responsible for loading the plugin at the time of instantiation of the framework
  3. MessageContext trait – All messages would extend this trait. This makes easy to pass a variety of messages to the plugin without restricting it to a few

Let us look at each of these one by one. Our Plugin trait looks like this

As you would notice, the implementation class would be defining a name, it would have an implementation for a performAction method which takes input as a MessageContext. We expect all our plugins to finally return the result with the result method.

A sample implementation of the plugin would look like this

Now, let us look at the Plugin manager

Now, the consumer who needs to use a plugin,  would come to the PluginManager and ask for a plugin via the getPlugin() method. If you remember, each plugin defines its name.

When this method is called, the managers checks if the plugin map is empty. If it is then the init is called where we load the plugins into the framework. Loading the plugins is done on the basis of all classes which are extending the
com.vajra.plugin.VajraPlugin trait. For this, we use are using a utility (ClassFinder) provided by Clapper. More details can be found here.

The idea is simple. As soon as we are starting the framework, we should not have to specify the plugins that the framework would be using anywhere in any configuration. The framework should be able to pick up the plugins automatically. In our case, we pick up all the plugins which are implementing our plugin trait i.e. VajraPlugin

The last piece in our puzzle is the message which is passed to the plugin. Since we want to keep this also extensible, instead of passing the message directly, we use a trait MessageContext.

As you would notice we have a number of utility methods here which all the messages would be implementing. We have a large number of methods here because they are relevant to our system. You could have the relevant methods for your system. A typical message which extends the MessageContext would look like this

The main takeaways are that you should definitely have all the plugins extend a trait. The plugin manager is responsible for creation, destruction and maintenance of plugins. The object passed to the plugin should (could) be a trait so that the framework can be extensible.

Written by 

Vikas is the CEO and Co-Founder of Knoldus Inc. Knoldus does niche Reactive and Big Data product development on Scala, Spark, and Functional Java. Knoldus has a strong focus on software craftsmanship which ensures high-quality software development. It partners with the best in the industry like Lightbend (Scala Ecosystem), Databricks (Spark Ecosystem), Confluent (Kafka) and Datastax (Cassandra). Vikas has been working in the cutting edge tech industry for 20+ years. He was an ardent fan of Java with multiple high load enterprise systems to boast of till he met Scala. His current passions include utilizing the power of Scala, Akka and Play to make Reactive and Big Data systems for niche startups and enterprises who would like to change the way software is developed. To know more, send a mail to hello@knoldus.com or visit www.knoldus.com

1 thought on “Building a Plugin Based Architecture in Scala

Leave a Reply

%d bloggers like this: