Skip to content
Advertisement

ArchUnit packages usage with exceptions for subpackages

I got seemingly trivial use-case, and still I cannot figure it out. Let’s take a look at the package structure.

-- CommonPackage
-- Package1
---- DAOs
---- Common
---- Service
-- Package2
---- subpackage1
---- subpackage2

What I want to achieve is to create a rule, in which all the classes in the Package2, cannot use any of the classes from Package1 EXCEPT the common one. So far I’ve came with something like this:

noClasses()
    .that()
    .resideInAPackage("package2..")            
    .should()
    .resideInAnyPackage("package1..")
    // and how write eg. except("package1.common")
    .check(classes);

But I cannot figure out how to exlude package1.common from this equasion. Can anyone help?

Advertisement

Answer

I assume that you forgot to include a .dependOnClassesThat() in your question.
(Classes in package2 just don’t reside in package1… 😉)

If your constraints cannot be expressed by the fluent API, consider using more powerful APIs based on arbitrary ArchConditions or DescribedPredicates. For constraints expressed as a method call within the fluent API, you can usually find an equivalent predefined DescribedPredicate with the same name, e.g. dependOnClassesThat().resideInAPackage(pkg)dependOnClassesThat(resideInAPackage(pkg)). Your IDE should help you to find the right static import. From there, it’s often easy to compose more complex constraints without even having to implement custom ArchConditions or DescribedPredicates.

In your case, I guess you’re looking for something like this:

noClasses()
    .that().resideInAPackage("package2..")
    .should().dependOnClassesThat(
        resideInAnyPackage("package1..").and(
            not(resideInAnyPackage("package1.common.."))
        )
    )
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement