I might have a (partial) solution for you.
Create an ArchCondition
public static class NotBeUnreferenced extends ArchCondition<JavaClass> {
NotBeUnreferenced() {
super("is not referenced by any other compilation units");
}
@Override
public void check(JavaClass javaClass, ConditionEvents events) {
Set<JavaAccess<?>> accessesFromOtherCompilationUnits = new HashSet<JavaAccess<?>>();
accessesFromOtherCompilationUnits.addAll(javaClass.getAccessesToSelf());
accessesFromOtherCompilationUnits.removeAll(javaClass.getAccessesFromSelf());
if (accessesFromOtherCompilationUnits.isEmpty() && javaClass.getDirectDependenciesToSelf().isEmpty()) {
String message = createCheckMessage(javaClass, "is unreferenced");
events.add(new SimpleConditionEvent(javaClass, false, message));
}
}
// taken from com.tngtech.archunit.lang.conditions.ArchConditions
public static <T extends HasDescription & HasSourceCodeLocation> String createCheckMessage(T object,
String message) {
return object.getDescription() + " " + message + " in " + object.getSourceCodeLocation();
}
}
Use the ArchCondition
ArchCondition<JavaClass> notBeUnreferenced = new NotBeUnreferenced();
ArchRule rule = classes().should(notBeUnreferenced);
collectedRules.add(rule);
You might want to
- exclude classes with certain annotations (e.g.,
@EJB
, @Dependent
, @Stateless
) by appending an or-condition (rule = rule.or(ArchConditions.beAnnotatedWith(...))
)
- exclude code from test classes
- exclude classes and interfaces that only exhibit constants
Known limitations
Note that a compilation unit (class, interface, enum) is considered unreferenced if the only access is
- an access to
.class
and other reflective access
- an access to a constant (i.e., a static final field)