Android使用标准logback而非logback-android报错,求排查方案
Android中使用标准Logback报错的解决方案
问题描述
在Android项目中尝试使用标准Logback而非Logback-Android配置日志,依赖如下:
implementation 'org.slf4j:slf4j-api:2.0.7' implementation 'ch.qos.logback:logback-classic:1.4.7' implementation 'ch.qos.logback:logback-core:1.4.7'
配置文件app\src\main\resources\logback.xml内容:
<?xml version="1.0" encoding="UTF-8"?> <configuration> <appender name="Logcat" class="ch.qos.logback.classic.android.LogcatAppender"> <encoder> <Pattern>%date %level %msg%n</Pattern> </encoder> </appender> <appender name="File" class="ch.qos.logback.core.FileAppender"> <file>./log/test.log</file> <encoder> <pattern>%date %level %msg%n</pattern> </encoder> </appender> <root level="debug"> <appender-ref ref="Logcat" /> <appender-ref ref="File"/> </root> </configuration>
使用Logger的代码:
class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val logger = LoggerFactory.getLogger("qwdqwd") logger.debug("hello") setContent { AndroidcomposelatestTheme { Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) { ArticleScreen2() } } } } }
运行时报错:
java.lang.NoSuchMethodError: No virtual method getModule()Ljava/lang/Module; in class Ljava/lang/Class; or its super classes (declaration of 'java.lang.Class' appears in /apex/com.android.runtime/javalib/core-oj.jar) 2023-05-22 09:47:22.672 4644-4644 System.err com.sage W at ch.qos.logback.core.util.EnvUtil.logbackVersionByModule(EnvUtil.java:56) 2023-05-22 09:47:22.672 4644-4644 System.err com.sage W at ch.qos.logback.core.util.EnvUtil.logbackVersion(EnvUtil.java:36) 2023-05-22 09:47:22.672 4644-4644 System.err com.sage W at ch.qos.logback.classic.util.ContextInitializer.autoConfig(ContextInitializer.java:81) 2023-05-22 09:47:22.672 4644-4644 System.err com.sage W at ch.qos.logback.classic.util.ContextInitializer.autoConfig(ContextInitializer.java:77) 2023-05-22 09:47:22.672 4644-4644 System.err com.sage W at ch.qos.logback.classic.spi.LogbackServiceProvider.initializeLoggerContext(LogbackServiceProvider.java:50) 2023-05-22 09:47:22.672 4644-4644 System.err com.sage W at ch.qos.logback.classic.spi.LogbackServiceProvider.initialize(LogbackServiceProvider.java:41) 2023-05-22 09:47:22.672 4644-4644 System.err com.sage W at org.slf4j.LoggerFactory.bind(LoggerFactory.java:183) 2023-05-22 09:47:22.672 4644-4644 System.err com.sage W at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:170) 2023-05-22 09:47:22.672 4644-4644 System.err com.sage W at org.slf4j.LoggerFactory.getProvider(LoggerFactory.java:455) 2023-05-22 09:47:22.672 4644-4644 System.err com.sage W at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:441) 2023-05-22 09:47:22.672 4644-4644 System.err com.sage W at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:390) 2023-05-22 09:47:22.672 4644-4644 System.err com.sage W at com.sage.MainActivity.onCreate(MainActivity.kt:57) 2023-05-22 09:47:22.672 4644-4644 System.err com.sage W at android.app.Activity.performCreate(Activity.java:8214) 2023-05-22 09:47:22.672 4644-4644 System.err com.sage W at android.app.Activity.performCreate(Activity.java:8202) 2023-05-22 09:47:22.672 4644-4644 System.err com.sage W at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1320) 2023-05-22 09:47:22.672 4644-4644 System.err com.sage W at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4033) 2023-05-22 09:47:22.672 4644-4644 System.err com.sage W at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4247) 2023-05-22 09:47:22.672 4644-4644 System.err com.sage W at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:91) 2023-05-22 09:47:22.672 4644-4644 System.err com.sage W at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:149) 2023-05-22 09:47:22.673 4644-4644 System.err com.sage W at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:103) 2023-05-22 09:47:22.673 4644-4644 System.err com.sage W at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2613) 2023-05-22 09:47:22.673 4644-4644 System.err com.sage W at android.os.Handler.dispatchMessage(Handler.java:110) 2023-05-22 09:47:22.673 4644-4644 System.err com.sage W at android.os.Looper.loop(Looper.java:219) 2023-05-22 09:47:22.673 4644-4644 System.err com.sage W at android.app.ActivityThread.main(ActivityThread.java:8668) 2023-05-22 09:47:22.673 4644-4644 System.err com.sage W at java.lang.reflect.Method.invoke(Native Method) 2023-05-22 09:47:22.673 4644-4644 System.err com.sage W at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513) 2023-05-22 09:47:22.673 4644-4644 System.err com.sage W at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1109)
报错原因
- Java版本API不兼容:
getModule()是Java 9引入的方法,而Android运行时(ART)基于Java 8(仅部分版本支持有限的Java 8+特性),标准Logback 1.4.x依赖Java 9+ API,导致在Android环境出现方法找不到的错误。 - 错误引用Logback-Android专属组件:配置文件中使用的
ch.qos.logback.classic.android.LogcatAppender是Logback-Android特有的Appender,标准Logback中不存在该类,且未引入对应依赖。 - 标准Logback不适配Android环境:标准Logback为Java SE设计,未适配Android的文件系统权限、Logcat集成等特性,在Android上运行会有兼容性问题。
解决方案
1. 替换为Logback-Android依赖
放弃标准Logback,改用专门适配Android的Logback-Android,修改项目依赖:
implementation 'org.slf4j:slf4j-api:1.7.36' implementation 'com.github.tony19:logback-android:2.0.0'
注:Logback-Android已内置适配后的logback-core和logback-classic,无需再引入标准Logback依赖。
2. 修正Logback配置文件
调整logback.xml,使用Logback-Android的正确组件,并适配Android存储路径:
<?xml version="1.0" encoding="UTF-8"?> <configuration> <!-- Logcat输出配置 --> <appender name="Logcat" class="ch.qos.logback.classic.android.LogcatAppender"> <encoder> <pattern>%date %level [%thread] %logger{36} - %msg%n</pattern> </encoder> </appender> <!-- 文件输出配置,使用应用专属外部存储路径 --> <appender name="File" class="ch.qos.logback.core.FileAppender"> <file>${EXT_DIR}/log/test.log</file> <encoder> <pattern>%date %level [%thread] %logger{36} - %msg%n</pattern> </encoder> <append>true</append> </appender> <root level="debug"> <appender-ref ref="Logcat" /> <appender-ref ref="File" /> </root> </configuration>
内置路径变量说明:
INT_DIR指向应用内部存储目录,EXT_DIR指向应用专属外部存储目录,无需硬编码路径,避免权限问题。
3. 配置存储权限(若使用外部存储)
如需写入外部存储,在AndroidManifest.xml中添加对应权限:
<!-- Android 10及以下 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Android 11及以上,应用专属外部存储无需额外权限,可直接读写。
4. 验证代码
原Logger使用代码无需修改,保持即可。
内容的提问来源于stack exchange,提问作者SageJustus
相关产品推荐
相关产品推荐

