You are here
ArchUnit rules and arrays
ArchUnit can be used to test dependencies between packages in Java. I use it to test that application slices do not depend on each other, but are disjunct:
@Test public void disjunctPackages() { JavaClasses importedClasses = new ClassFileImporter().importPackages("de.stevenschwenke.java.blubber"); SliceRule sliceRule = slices().matching("de.stevenschwenke.java.blubber.(*)..").should().notDependOnEachOther(); sliceRule.check(importedClasses); }
Sometimes, certain packages are used by other slices. A good example are "common", "base" or "share" packages that include data transfer objects. These packages can be excluded like this:
@Test public void disjunctPackages() { JavaClasses importedClasses = new ClassFileImporter().importPackages("de.stevenschwenke.java.blubber"); SliceRule sliceRule = slices().matching("de.stevenschwenke.java.blubber.(*)..").should().notDependOnEachOther() .ignoreDependency(alwaysTrue(), nameMatching("de\\.stevenschwenke\\.java\\.blubber\\.base\\..*")); sliceRule.check(importedClasses); }
An interesting problem arises when a class does not refer to a base-class in a single-fashioned way, let's say like this:
private SomeBaseClass someBaseClass;
... but as an array like this:
private SomeBaseClass[] someBaseClass;
Arrays are of different type than the class they come with. They also live in another package. Hence, the sliceRule shown above will fail:
java.lang.AssertionError: Architecture Violation [Priority: MEDIUM] - Rule 'slices matching 'de.stevenschwenke.java.blubber.(*)..' should not depend on each other' was violated (1 times): Slice xyz depends on Slice base: Constructor <de.stevenschwenke.java.xyz.SomeClass.<init>(...)> has parameter of type <[Lde.stevenschwenke.java.base.SomeBaseClass;> in (SomeClass.java:0)
ArchUnit seems to "place" arrays in the package of the base class, beginning with "[L", see this discussion. Hence, I use this workaround to cover arrays for the use case stated above:
.ignoreDependency(alwaysTrue(), nameMatching("\\[Lde\\.stevenschwenke\\.java\\.base\\..*"))
UPDATE
Thanks to a tweet from the ArchUnit-team, I changed my code to this solution which is way better than mine:
.ignoreDependency(alwaysTrue(), resideInAPackage("de.stevenschwenke.java.base..*"))