Architecture Definition
What is a Logical Architecture?
SonarJ's main benefit is its ability to check a given set of Java source and class files to its conformance to a given logical architecture in real time. But before you can profit from this benefit you must first define the logical architecture that should be used as the blueprint for your system.
SonarJ defines several elements that allow you to incrementally develop your vision of the internal structure of your system. To structure your system you will probably first cut it horizontally into technical layers (e.g. user interface, business logic, data access). So the first architecture element defined by SonarJ is a "layer".
As a next step you will probably use domain driven aspects to cut your system vertically into so called "vertical slices". Therefore "vertical slices" are the second logical element used to describe a logical architecture with SonarJ.
If you look at the resulting structure you will see, that it looks like a grid. The intersections of this grid are what we call "natural subsystems". The tool also supports higher level abstractions like projects, layer groups and vertical slice groups.
SonarJ Architecture Grid View (Patent Pending)
If you have cut your system horizontally and vertically (optional) you might want to define the legal usage relations between layers and vertical slices. You probably will establish rules like "User interface can use business logic" or "our Contract slice can access the customer slice" By specifying allowed usage relations between layers and vertical slices you greatly reduce the allowed usage relations between subsystems. In fact it is easily possible to compute the remaining legal usage relations out of the rules defined on the high level elements "layer" and "vertical slice".
If your system is cut into several projects, SonarJ will allow you to define "global" architectural artifacts, which are visible and assignable within all your projects.
Physical Mapping of Architecture to Java Code
As soon as you have defined some architectural artifacts you can now map them to your Java code. You simply assign Java types to artifacts like layers, slices or subsystems. In most cases you will have some kind of naming strategy for your packages and types in place so that the assignment can be done by using simple patterns like "**.controller.**".
If you want to restrict the access to a subsystem to a subset of the public classes exported by the packages defining the subsystem you can do so by defining one or more "named interfaces" for the subsystem.