DSM: Prepare Your Application for Modularity
Tracking dependencies between application components can be difficult. Complicated relationships and cyclic dependencies might seriously affect application performance and behavior, and hinder the reuse of components. But what if you could see the dependencies in your application? IntelliJ IDEA Ultimate has the perfect tool for this: DSM analysis.
DSM stands for Dependency Structure Matrix – a method that visualizes dependencies between modules, classes, and other project components and highlights the usage flow between them.
DSM analysis can help you complete many tasks, even the ones that are a little more daring. For example, if you are about to migrate to modular Java (version 9 or later), DSM analysis can help you prepare your application for the change.
You can find and fix all mutual dependencies, also known as cyclic dependencies, that are not allowed in modular Java. These dependencies are highlighted with a red frame in the matrix.
Our matrix shows that new-module and spring-petclinic depend on each other. If your application is massive, you don’t need to expand all the nodes one by one to find all the cyclic dependencies. Just press F2 or select Go to Next Cycle from the context menu to quickly jump to the next cycle.
Split packages may be another obstacle in your way to a modular application. In such packages, two or more members are split over several modules. They compile without errors in Java 8, but often cause problems when switching to Java 9 and later.
There are various ways of solving the split-package problem. For example, you can move the package from the two modules into a new module, or you might rename the package in one of the modules, or, in some cases, you can combine the two modules into one. There’s no one universal solution. But still, DSM analysis can help you pick the one that works for your application: you can see the number of dependencies in each component and predict how the changes will propagate through the project.
How to read the matrix
In the matrix, dependencies unfold from top to bottom: a row catches the dependent components from above, and a column drops dependencies on the selected component below. Let’s see how it works in practice.
Say we want to know all the dependencies between the org.springframework.samples.petclinic.visit package and other packages in the application. Let’s click this package.
The row shows dependencies on the selected component. This means that other components depend on the selected one, and they are marked green in the matrix. In our example, the owner package has 18 dependencies on visit.
The column displays dependencies of this component. This means that the selected component depends on the other ones, and they are marked yellow in the matrix. In our case, the visit package has two dependencies on model.
By doing so, you can dig into each package and analyze dependencies between classes in your application. Note that those components are not sorted alphabetically. The matrix moves the components that are used most to the bottom. This means that if there are no cycles, or there are only a few of them, the components located at the top of the matrix depend on the components below them.
Now it’s your turn: open your project, select Analyze | Analyze Dependency Matrix from the main menu, and specify exactly what you want to analyze: the entire project or a specific scope.
The IDE might prompt you to recompile the project so that all components are up to date. This is necessary because DSM analyzes bytecode and not source code, which is what makes this tool so efficient: analyzing more than 100,000 classes in an IntelliJ IDEA Ultimate project only takes two minutes.
DSM works in IntelliJ IDEA Ultimate and requires the Dependency Structure Matrix plugin, which is bundled and enabled by default. If you want to know more about this tool, see the DSM Analysis documentation page. Enjoy!