Tobias
Tobias

Reputation: 2575

ArchUnit ignoreDependency for classes rule

In my project I'm using some simple ArchRule test to ensure that there are no unwanted dependencies between packages. Most of them work fine, but the following test leads to a problem (test source on github):

@ArchTest
private final ArchRule networkPackagesMustNotDependOnOtherPackagesOutsideNetwork = classes().that() //
            .resideInAPackage("..onnessium.network.shared..") //
            .should().onlyDependOnClassesThat() //
            .resideInAnyPackage("..onnessium.network..", "java..", "com.esotericsoftware.kryo..", "com.esotericsoftware.kryonet..");

This rule finds a violation in the class PasswordEncryptor (source on github):

public class PasswordEncryptor {
    
    private static final char[] ENCRYPTION_KEY = "password".charArray();

    // ...
}

The cause of the violation is the char[]. The violation says:

Field <...PasswordEncryptor.ENCRYPTION_KEY> has type <[C> in (PasswordEncryptor.java:0)

I found this issue on GitHub that explains how to solve this kind of problem for tests that are based on Architectures.layeredArchitecture(), but I couldn't figure out how to do something similar when using a classes()... rule.

So my question is: is there something similar to ignoreDependency (like described in this issue) for tests that use classes().that()... instead of a layered architecture? Or should I change the tests to use Architecture.layeredArchitecture()?

Upvotes: 1

Views: 804

Answers (1)

Manfred
Manfred

Reputation: 3062

ArchUnit (as of the current version 0.23.1) assigns char[] to the empty package "" (probably because char[].class.getPackage() == null). (Side note: I just realized that char[].class.getPackageName(), available with JRE ≥9, actually returns "java.lang"... 🙀)

If you want to allow for primitives and arrays of primitives, you can simply allow for the empty package:

@ArchTest
private final ArchRule networkPackagesMustNotDependOnOtherPackagesOutsideNetwork = classes().that() //
    .resideInAPackage("..onnessium.network.shared..") //
    .should().onlyDependOnClassesThat() //
    .resideInAnyPackage(ArchUnitUtils.addAllLibraryPackages("..onnessium.network.."
        // <fix> <!-- just 3 characters 😜 -->
        , ""
        // </fix>
    ));

Upvotes: 1

Related Questions