commons-net 3.9.0的FTPClient不兼容Android7及以下,有无兼容方案?
问题描述
我使用Apache Commons Net的FTPClient下载文件,3.8.0版本一切正常,但升级到3.9.0版本后,实例化FTPClient时应用崩溃,堆栈跟踪如下:
E FATAL EXCEPTION: main Process: com.mozyn.android.example, PID: 14556 java.lang.NoClassDefFoundError: Failed resolution of: Ljava/time/Duration; at org.apache.commons.net.ftp.FTPClient.<init>(FTPClient.java:544) at com.mozyn.android.example.services.DownloadService$startMyDownloadService$1$1$1$downloadResult$1.invokeSuspend(DownloadService.kt:188) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106) at kotlinx.coroutines.internal.LimitedDispatcher.run(LimitedDispatcher.kt:42) at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:95) at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664) Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@aa100d1, Dispatchers.Main] Caused by: java.lang.ClassNotFoundException: Didn't find class "java.time.Duration" on path: DexPathList[[zip file "/data/app/com.mozyn.android.example-1/base.apk"],nativeLibraryDirectories=[/data/app/com.mozyn.android.example-1/lib/x86_64, /vendor/lib64, /system/lib64]] at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56) at java.lang.ClassLoader.loadClass(ClassLoader.java:511) at java.lang.ClassLoader.loadClass(ClassLoader.java:469) ... 10 more Suppressed: java.lang.ClassNotFoundException: java.time.Duration at java.lang.Class.classForName(Native Method) at java.lang.BootClassLoader.findClass(ClassLoader.java:781) at java.lang.BootClassLoader.loadClass(ClassLoader.java:841) at java.lang.ClassLoader.loadClass(ClassLoader.java:504) ... 11 more Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available
其中DownloadService.kt:188对应FTPClient()构造方法,FTPClient.java:544对应代码private Duration controlKeepAliveTimeout = Duration.ZERO;。
我注意到3.9.0版本的FTPClient使用了仅支持API 26+的java.time API,当前依赖为:
implementation("commons-net:commons-net:3.9.0")
想请教:是否有办法升级到3.9.0版本同时支持Android 7及以下,还是只能停留在3.8.0版本?
解决方案
可以升级到3.9.0版本同时兼容Android 7(API 24及以下),有两种可行方案:
方案一:启用Android核心库脱糖
Android提供了对Java 8+ API的兼容支持,通过核心库脱糖可以将java.time等高版本API转换为低版本Android兼容的实现:
- 在模块的
build.gradle.kts中启用Java 8兼容和脱糖:
android { compileOptions { coreLibraryDesugaringEnabled = true sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = "1.8" } }
- 添加脱糖依赖:
dependencies { coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.4") implementation("commons-net:commons-net:3.9.0") }
方案二:使用Apache Commons Net的Android专属变体
从3.9.0版本开始,Apache Commons Net提供了专门适配Android的变体,该变体替换了java.time相关API为兼容低版本系统的实现,直接引入即可:
implementation("commons-net:commons-net:3.9.0-android")
如果以上两种方案都无法适配你的项目,再考虑回退到3.8.0版本。
内容的提问来源于stack exchange,提问作者user21928976
相关产品推荐
相关产品推荐

