TNG / ArchUnit

A Java architecture test library, to specify and assert architecture rules in plain Java
http://archunit.org
Apache License 2.0
3.23k stars 298 forks source link

Avoid imports/use of unwanted classes #124

Closed ThStock closed 5 years ago

ThStock commented 5 years ago

Is it possible to add a rule that check my classes for unwanted imports e.g. if I only want:

com.google.common.base.Strings

but in my classpath are:

com.google.common.base.Strings
org.bouncycastle.util.Strings
com.tngtech.archunit.thirdparty.com.google.common.base.Strings
codecholeric commented 5 years ago

You can per se not do any checks of imports with ArchUnit, since ArchUnit operates on bytecode and import statements live only in source code (and vanish on compile). You can however forbid that any class depends on an evil implementation like

noClasses().should().dependOnClassesThat()
    .haveFullyQualifiedName(org.bouncycastle.util.Strings.class.getName())

Or you could write a little more sophisticated custom code to make this more generic:

classes().should(onlyHaveDependenciesTo(com.google.common.base.Strings.class))

...

ArchCondition<JavaClass> onlyHaveDependenciesTo(final Class<?> allowedType) {
    return new ArchCondition<JavaClass>("only have dependencies to " + allowedType.getName()) {
        @Override
        public void check(JavaClass javaClass, ConditionEvents events) {
            javaClass.getDirectDependenciesFromSelf().stream()
                    .filter(d -> d.getTargetClass().getSimpleName().equals(allowedType.getSimpleName()))
                    .filter(d -> !d.getTargetClass().isEquivalentTo(allowedType))
                    .forEach(d -> events.add(SimpleConditionEvent.violated(d, d.getDescription())));
        }
    };
}

The last example would white list your allowed dependency and automatically grow if for some reason you get a further implementation of Strings on your classpath.

Does this help you?

ThStock commented 5 years ago

Yes both works very well.

codecholeric commented 5 years ago

Cool, I'll close this issue then :smiley: Feel free to open another one, if you should run into further problems!!