When the simplicity became complex
After more than 15 years developing multitenant technologies I’ve come across many situations where developing new technological features became complex due to the dependency of external technologies that lack a multitenant design. I think I can provide a good example that illustrates this situation. Some years ago I faced the problem of extending the Java runtime to support multitenant features.
Isolating collisions between different client instances
Java is a powerful language and comes with a rich runtime library and a vast internet support. Nevertheless if you try to use java in a multitenant environment you’ll face quickly some hard problems. One is the way Java handles the object instances. If you load an object (or a class) this object will be in the RAM memory forever. Now, let’s imagine that a customer of the multitenant environment loads a class called "A" that conflict with the class "A" used by another customer. A good multitenant technology should isolate such collisions in a way that any resource defined or used by a client (Java or not) never conflict with that of another customer. So we’ve had to expand the core loader of the Java runtime to support many classes loaded at a time, even with different versions of the same class. It was hard work, but the result has been very important to support many other new features based on Java technology. From the end user perspective, it seems very simple and we can implement many other new technologies based on the new multitenant Java runtime environment. The complexity was absorbed by the multitenant technology, working behind the scenes to simplify the end user tasks.
Managing evolution trough object inheritance
To understand how this complexity works, let’s imagine a global process implemented using an object called ‘ParentObject’. You can inherit this object and adjust it to create a slightly different, but new process. Let’s call this new object ‘ChildObject’. The multitenant technology will replace for a particular customer any instance of the parent object to the child one. So the developer doesn’t have to write a single line of code to replace and use the new behavior. It’s a simple configuration.
Inheritance, in this context, means that if you don’t change the new inherited or ChildObject it will behave exactly as the parent one. If you change a small piece in your new "ChildObject", that small piece will be exclusive to the child but all the other features will be like the original one. This means that any change applied in a normal maintenance cycle will be merged into your child object in a transparent way. No manual merging, errors, etc. You could also think that you might have more than one level or inheritance. This mechanism saves time and money while maintaining the platform stability.
You can also apply the same concept to other elements of the architecture like data or security.
Easy configuration and maintenance from the multitenant platform
Now suppose we’d like to replace the ParentObjet with the new ChildObjet only for some of our customers, but we know that there are hundreds of other processes used by these customers that depend on the ParentObject. In theory, we should change all these processes to use the new ChildObject instead of pointing to the ParentObject. A first-class technology should come with a simple mechanism to handle this behaviour and be able of performing a rollback if required.
In a multitenant environment customers use processes to complete tasks. In our case we map one process to one ‘Object’. This has many advantages. Objects, from a computational point of view, aggregate several properties that are very convenient if applied in a multitenant environment. Maintenance is one.. If you use a standard process or object from the multitenant platform you know that any update from the core technology will be automatically available to you. But what if you have to ‘tune’ a bit this process to match a specific requirement in your company? You could, of course, copy & paste the object and overwrite it. The problem is obvious: you will be alone to maintain it. However, as it is an object, you could inherit it from the original one.
Like I’ve said, multitenant technology + object orientation saves time and money.
In the next article we will show all this working together from a HR System perspective and the direct impact it has in terms ofeffort and cost.
Multitenancy: Multitenancy refers to a principle in software architecture where a single instance of the software runs on a server, serving multiple client organizations (tenants). Multitenancy is contrasted with a multi-instance architecture where separate software instances (or hardware systems) are set up for different client organizations. With a multitenant architecture, a software application is designed to virtually partition its data and configuration, and each client organization works with a customized virtual application instance. (Wikipedia)
Java: Java is a general-purpose, concurrent, class-based, object-oriented computer programming language that is specifically designed to have as few implementation dependencies as possible. It is intended to let application developers "write once, run anywhere" (WORA), meaning that code that runs on one platform does not need to be recompiled to run on another. (Wikipedia)
Java Runtime Library: The Java Runtime Environment (JRE) is a set of software tools for development of Java applications. It combines the Java Virtual Machine (JVM), platform core classes and supporting libraries. JRE is part of the Java Development Kit (JDK), but can be downloaded separately. JRE was originally developed by Sun Microsystems Inc., a wholly-owned subsidiary of Oracle Corporation. (Technopedia)
Objects: Objects in "object-oriented programming" are essentially data structures together with their associated processing routines. For instance, a file is an object: a collection of data and the associated read and write routines. Objects are considered instances of classes. In common speech one refers to a file as a class, while the file is the object. A class defines properties and behaviour once, usually for multiple instantiations. This distinction has its counterparts in other disciplines, for example in biology and evolution  and is known as the genus/species dichotomy. (Wikipedia)
Instance: An instance method defines behaviors of objects. A static method does not define object behavior, but is defined inside a class. (Wikipedia)
Parent Object: An object in which another object resides. For example, a folder is a parent object in which a file, or child object, resides. An object can be both a parent and a child object. For example, a subfolder that contains files is both the child of the parent folder and the parent folder of the files.
Child Object: An object than resides in a Parent Object, and inherits some of its characteristics.