bertolami
bertolami

Reputation: 2936

ArchUnit: How to avoid dependency violation to java classes

I want to verify, that classes within a given package, only refer to classes that reside in the package itself. However I get a violation, telling me that the a class depends on e.g. java.lang.String, which is totally ok for me. Is there a way to ignore the basic java packages?

        @ArchTest
        static final ArchRule zeroDependencyOfDomain = noClasses().that()
            .resideInAPackage("..domain..")
            .should().dependOnClassesThat()
            .resideOutsideOfPackages("..domain..");

Upvotes: 3

Views: 3527

Answers (3)

Tomasz Fijałkowski
Tomasz Fijałkowski

Reputation: 799

If you don't want to explicitly specify all external packages like java., javax., com.google., org.apache. etc. and you just care about project packages, then you can just join two conditions like "domain or external lib".

String PROJECT_PACKAGE = "com.myproject..";

DescribedPredicate<JavaClass> domainOrExternalLibPredicate = JavaClass.Predicates.resideInAnyPackage("..domain..")
    .or(JavaClass.Predicates.resideOutsideOfPackage(PROJECT_PACKAGE));

@ArchTest
static final ArchRule zeroDependencyOfDomain = classes().that()
    .resideInAPackage("..domain..")
    .should().onlyDependOnClassesThat()
    .resideInAnyPackage(domainOrExternalLibPredicate);

In this caste, external lib is defined as anything outside your PROJECT_PACKAGE.

Upvotes: 2

kapex
kapex

Reputation: 29959

You can explicitly allow dependencies to java packages:

@ArchTest
static final ArchRule zeroDependencyOfDomain = noClasses().that()
    .resideInAPackage("..domain..")
    .should().dependOnClassesThat()
    .resideOutsideOfPackages("..domain..", "java..");

You could also use classes() and onlyDependOnClassesThat(), which a bit easier to read in my opinion:

@ArchTest
static final ArchRule zeroDependencyOfDomain = classes().that()
    .resideInAPackage("..domain..")
    .should().onlyDependOnClassesThat()
    .resideInAnyPackage("..domain..", "java..");

Upvotes: 0

DerM
DerM

Reputation: 1526

Similar to the other answer, I also found no better way yet than this:

private static final String[] COMMON_PACKAGES = {
    "java..",
    "javax..",
    "com.google..",
    "org.springframework.."};

@ArchTest
final ArchRule classesInProdutPackageNoOutsideAccess =
    classes()
        .that()
        .resideInAnyPackage(PACKAGE_FOO)
        .should()
        .onlyAccessClassesThat()
        .resideInAnyPackage(commonPackagesAnd(PACKAGE_FOO));


private static String[] commonPackagesAnd(String... packages) {
    return ArrayUtils.addAll(packages, COMMON_PACKAGES);
}

Upvotes: 0

Related Questions