Dropwizard集成测试出现SLF4J多绑定警告问题求助
这个问题我太熟悉了!运行shaded jar一切正常,但集成测试跳SLF4J多绑定警告,本质就是测试阶段的类路径里同时存在多个SLF4J的日志绑定实现——shaded jar打包时已经把重复依赖处理掉了,但测试时Maven/Gradle会把所有相关依赖都拉进来,就撞车了。
1. 先定位重复依赖的来源
首先得搞清楚到底是哪个依赖带了多余的SLF4J绑定。用Maven的话,直接跑这个命令看依赖树:
mvn dependency:tree -Dincludes=org.slf4j,ch.qos.logback
如果是Gradle项目,就用这个:
./gradlew dependencies --configuration testRuntimeClasspath | grep -E "(slf4j|logback)"
从你的警告信息来看,graphhopper-web-0.11-SNAPSHOT.jar里自带了一个StaticLoggerBinder,而logback-classic-1.2.3.jar是另一个绑定,你需要确定哪个是你不需要的。
2. 排除多余的绑定依赖
找到重复的来源后,在构建文件里把多余的绑定排除掉。比如如果是graphhopper-web带了不必要的SLF4J绑定,Maven的pom.xml里这么改:
<dependency> <groupId>com.graphhopper</groupId> <artifactId>graphhopper-web</artifactId> <version>0.11-SNAPSHOT</version> <exclusions> <!-- 替换成实际的绑定artifactId,比如slf4j-simple或者其他 --> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> </exclusion> </exclusions> </dependency>
Gradle项目的话,这么写:
testImplementation('com.graphhopper:graphhopper-web:0.11-SNAPSHOT') { exclude group: 'org.slf4j', module: 'slf4j-simple' }
注意要对应正确的artifactId,不同的SLF4J绑定artifactId不一样(比如slf4j-log4j12、logback-classic等)。
3. 给测试阶段指定统一的日志配置
另外,你可以在src/test/resources下添加一个logback-test.xml(如果用logback的话),测试阶段会优先加载这个配置文件,既能统一日志行为,也能减少冲突概率。
4. 同步Shade插件的处理逻辑
既然运行shaded jar没问题,说明你的Shade插件可能已经做了依赖排除或重定位。可以检查下Shade插件的配置,比如是不是有类似这样的过滤:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <configuration> <filters> <filter> <artifact>*:*</artifact> <excludes> <exclude>org/slf4j/impl/**</exclude> </excludes> </filter> </filters> </configuration> </plugin>
如果有的话,把这个排除逻辑同步到测试依赖的处理里,就能保持和打包时一致的依赖环境了。
内容的提问来源于stack exchange,提问作者Karussell

