With a new greenfield project, you can and should decide on a suitable architecture from the outset and pour it into appropriate (Maven) modules, each with their own dependencies. With so many grown or overgrown heirlooms, this is no longer possible afterwards. The structure of these treasures must be recognized and constantly improved. In this article, you will learn how to do this systematically. A small Java library is used for this, which can be used to check dependencies between classes.
In the early 2000s, as a junior developer in a classic EJB 2.0 project, I had the task of writing (unit) tests in order to somehow improve the code quality afterwards. This task turned out to be extremely difficult because everything was intertwined and you couldn't test partial functionality without booting up the whole application. The application ran rather badly than well, there were always problems, errors were difficult to understand and supposed bug fixes led to new problems. An external consultant was therefore consulted. Together with the architect, he worked out the structure of the project and identified a solution. This resulted in an extensive refactoring project in which cyclic dependencies in particular were resolved.
An open source tool called Dependometer was used to monitor progress . I used the tool in follow-up projects, but soon realized that no one had the time to analyze complicated HTML reports in the stressful day-to-day work of a project. A red traffic light in the CI environment would be ideal, indicating architecture violations, similar to a failed unit test. So nothing is more obvious than implementing such architecture checks as a unit test. However, suitable libraries for this were scarce and brought with them dependency conflicts. I therefore decided to write my own library for this purpose, which has no dependencies and makes do with a very old Java version (Java 6) so that it can really be used with any heirloom. Of course, the library also runs with newer Java versions up to Java 16.