如何使用 ArchUnit 在 Java 代码中强制使用 SLF4J

How to enforce SLF4J usage in Java code with ArchUnit

我想使用 ArchUnit to enforce usage only SLF4J logging framework 并避免简单的 System.out 调用。我也想避免使用任何其他日志记录框架。我怎样才能执行这样的检查?

目前我正在写这个测试

class EnforceSlf4JLoggingTest {

    private final JavaClasses importedClasses = new ClassFileImporter()
            .withImportOption(new ImportOption.DoNotIncludeTests())
            .importPackages("... my packages ...");

    @Test
    public void classesShouldNotUseJavaUtilLogging() {
        NO_CLASSES_SHOULD_USE_JAVA_UTIL_LOGGING.check(importedClasses);
    }

    @Test
    public void classesShouldNotUseSystemOutLogging() {
        noClasses()
                .should()
                .dependOnClassesThat()
                .belongToAnyOf(java.lang.System.class)
                .because("use SLF4J instead")
                .check(importedClasses);
    }
}

但它实际上并不强制使用 SLF4J,而只是限制 java.unit.logging 使用并防止依赖于 java.lang.System class(实际上 System.out 常量位于).

我的情况是否有更优雅的解决方案?

没有简单的方法可以避免使用除 SLF4J 之外的任何其他 loggig 系统,但可以使用此 ArchUnit 检查模板

ArchRuleDefinition.noClasses()
  .should().dependOnClassesThat()
  .resideInAnyPackage(
    "java.util.logging..", 
    "org.apache.logging.."
  ).as("Please only depend on SLF4J as a logging framework");

resideInAnyPackage部分应该指定避免不同日志系统的包。

此外,规则

com.tngtech.archunit.library.GeneralCodingRules.NO_CLASSES_SHOULD_ACCESS_STANDARD_STREAMS 

必须用于检查代码中是否存在任何普通的 System.outSystem.errprintStackTrace 调用。