We've noticed that when declaring a rule about allowed module dependencies, like so:
modules().definedByPackages("..root.(*)..").should().respectTheirAllowedDependencies(allow().fromModule("main").toModules("util"))
If there are multiple violations of this rule, the generated violation message has non-deterministic ordering.
Example violation message:
Module Dependency [main -> util]:
Method <util.UtilClass.foo()> calls method <main.SomeMainClass.bar()> in (UtilClass.java:12)
Method <othermodule.OtherClass.baz()> calls method <util.UtilClass.foo()> in (OtherClass.java:34)
Although it is functionally correct (the list includes all offending places), the fact that it may give a different ordering every time leads to problems when using the frozen rule mechanism, which checks against already known violations. Because the violation text isn't completely equal, it is seen as a new violation and therefore fails the test.
Problem:
The getDescription() method of the ModuleDependency class iterates over the classDependencies field, which is a Set. Although that set should preserve its insertion order, it seems that the order in which it gets populated can differ with each ArchUnit analysis run.
Solution alternatives:
- Make sure that the set of class dependencies that get inserted here always have deterministic ordering. Seems error prone / difficult to achieve: how will we ensure we have catched all places from which this could be populated?
- Make sure that, regardless of insertion order, the
getDescription() method always produces deterministic output, for instance by putting a .sorted() operation into its stream. Seems like a small enough fix and even leads to better readable violation messages.
We've noticed that when declaring a rule about allowed module dependencies, like so:
modules().definedByPackages("..root.(*)..").should().respectTheirAllowedDependencies(allow().fromModule("main").toModules("util"))If there are multiple violations of this rule, the generated violation message has non-deterministic ordering.
Example violation message:
Although it is functionally correct (the list includes all offending places), the fact that it may give a different ordering every time leads to problems when using the frozen rule mechanism, which checks against already known violations. Because the violation text isn't completely equal, it is seen as a new violation and therefore fails the test.
Problem:
The
getDescription()method of theModuleDependencyclass iterates over theclassDependenciesfield, which is a Set. Although that set should preserve its insertion order, it seems that the order in which it gets populated can differ with each ArchUnit analysis run.Solution alternatives:
getDescription()method always produces deterministic output, for instance by putting a.sorted()operation into its stream. Seems like a small enough fix and even leads to better readable violation messages.