A while back I said Armedia was investing in the next generation ArkCase. I promised occasional updates. Since then I’ve written a few technical stories (CLICK HERE to view all of our ArkCase blog posts). Today I want to describe how we’ve started to achieve modularity, one of my key goals for the new ArkCase platform.
Modularity means each module should be cohesive and minimally coupled to other modules. How do we decide what is cohesive? How do we judge which functions and features belong together in one module?
In the next-generation ACM, there is no single database script module, and no single JSP/JS/CSS module, and Spring MVC controllers are in the same module with the corresponding business service.
We use Liquibase to manage the database scripts. Liquibase supports classpath scanning to find DDL scripts to run. So we setup a standard classpath location to store DDL scripts. Each module that requires database storage has its own database scripts, stored in this standard classpath location. When the application starts, Liquibase scans for and runs all such scripts.
The Servlet 3.0 specification allows resources to be served from the META-INF/resources folder of JAR files stored in the WEB-INF/lib folder. In other words: JSP/JS/CSS files can be stored right in a module JAR file! They do not all have to be in the webapp project’s resources folder. Obviously this applies only to module-specific web resources. Libraries like jQuery or Bootstrap are still stored in a central location! Not repeated in all the modules that need them.
Lastly, we decided to store the Spring MVC controllers along with the business services. Obviously Spring has known how to scan the classpath for configuration files for ages. But Spring MVC always sets up its own child application context to the main Spring context. Since the Spring MVC context is a child context, the Spring MVC controller beans and the business service beans have to be defined in different Spring configuration files. The main Spring application context scans for business service configuration files in a certain location, and the dispatcher servlet scans for Spring MVC beans in another location.
These 3 changes mean we can store database scripts, JSP/JS/CSS files, and all Spring beans on a per-module basis. So now I know all resources specific to the case file module are stored directly in the case file module; and all resources specific to tasks are in the task module. If I need to specialize the case file for a specific customer, I have one module to start from.
The solution is not yet perfect. The Servlet 3.0 META-INF/resources folder mechanism only works for JAR’s deployed to the WEB-INF/lib folder: that is, only JAR’s deployed along with the web application itself. This means the application has to be fully assembled at deployment time. Ideally we could deploy new modules at runtime. Atlassian’s JIRA and Bamboo, and the open-source Jenkins project all allow the administrator to add new modules at runtime, without restarting the web application. All 3 projects made this happen via pretty heavy-duty engineering. I hope to report soon how we accomplish runtime module loading in ArkCase.