Android中使用Apache SSH时遭遇java.lang.ClassNotFoundException问题
解决Android中使用Apache SSHD建立SSH连接时的NoClassDefFoundError问题
问题现象
在Android应用中通过Java实现SSH连接时,建立连接阶段抛出NoClassDefFoundError,提示无法解析javax.management.ReflectionException类。
异常栈信息
FATAL EXCEPTION: main Process: com.example.atest, PID: 14392 java.lang.NoClassDefFoundError: Failed resolution of: Ljavax/management/ReflectionException; at org.apache.sshd.common.util.GenericUtils.peelException(GenericUtils.java:728) at org.apache.sshd.common.future.AbstractSshFuture.verifyResult(AbstractSshFuture.java:121) at org.apache.sshd.client.future.DefaultConnectFuture.verify(DefaultConnectFuture.java:42) at org.apache.sshd.client.future.DefaultConnectFuture.verify(DefaultConnectFuture.java:34) at com.example.atest.MainActivity.sshConnect(MainActivity.java:372) at com.example.atest.MainActivity.onResults(MainActivity.java:335) at android.speech.SpeechRecognizer$InternalRecognitionListener$1.handleMessage(SpeechRecognizer.java:1062) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loopOnce(Looper.java:230) at android.os.Looper.loop(Looper.java:319) at android.app.ActivityThread.main(ActivityThread.java:8893) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:608) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103) Caused by: java.lang.ClassNotFoundException: Didn't find class "javax.management.ReflectionException" on path: DexPathList[[dex file "/data/data/com.example.atest/code_cache/.overlay/base.apk/classes4.dex", dex file "/data/data/com.example.atest/code_cache/.overlay/base.apk/classes5.dex", zip file "/data/app/~~iTqpPkZDjYiDFfzmOJt2nQ==/com.example.atest-uHpPjOVd-8RZr-nUHh2kaw==/base.apk"],nativeLibraryDirectories=[/data/app/~~iTqpPkZDjYiDFfzmOJt2nQ==/com.example.atest-uHpPjOVd-8RZr-nUHh2kaw==/lib/arm64, /data/app/~~iTqpPkZDjYiDFfzmOJt2nQ==/com.example.atest-uHpPjOVd-8RZr-nUHh2kaw==/base.apk!/lib/arm64-v8a, /system/lib64, /system/system_ext/lib64]] at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:259) at java.lang.ClassLoader.loadClass(ClassLoader.java:379) at java.lang.ClassLoader.loadClass(ClassLoader.java:312) at org.apache.sshd.common.util.GenericUtils.peelException(GenericUtils.java:728) at org.apache.sshd.common.future.AbstractSshFuture.verifyResult(AbstractSshFuture.java:121) at org.apache.sshd.client.future.DefaultConnectFuture.verify(DefaultConnectFuture.java:42) at org.apache.sshd.client.future.DefaultConnectFuture.verify(DefaultConnectFuture.java:34) at com.example.atest.MainActivity.sshConnect(MainActivity.java:372) at com.example.atest.MainActivity.onResults(MainActivity.java:335) at android.speech.SpeechRecognizer$InternalRecognitionListener$1.handleMessage(SpeechRecognizer.java:1062) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loopOnce(Looper.java:230) at android.os.Looper.loop(Looper.java:319) at android.app.ActivityThread.main(ActivityThread.java:8893) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:608) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)
当前依赖配置
app/build.gradle中的dependencies配置:
dependencies { implementation "org.apache.mina:mina-core:3.0.0-M2" implementation "org.apache.sshd:sshd-core:2.1.0" implementation "org.apache.sshd:sshd-putty:2.1.0" implementation "org.apache.sshd:sshd-common:2.1.0" implementation "org.slf4j:slf4j-api:1.7.5" implementation "org.slf4j:slf4j-simple:1.6.4" }
SSH连接实现代码
public void sshConnect(String username, String password, String host, int port, long defaultTimeoutSeconds, String command) { // create a client instance try (SshClient client = SshClient.setUpDefaultClient()) { client.start(); Log.d(TAG, "sshConnect(): client.start(): client started"); // connection and authentication try (ClientSession session = client.connect(username, host, port).verify(TimeUnit.SECONDS.toMillis(defaultTimeoutSeconds)).getSession()) { Log.d(TAG, "ssh: client.connect()"); session.addPasswordIdentity(password); session.auth().verify(TimeUnit.SECONDS.toMillis(defaultTimeoutSeconds)); Log.d(TAG, "ssh: connection established"); // create a channel to communicate channel = session.createChannel(Channel.CHANNEL_SHELL); Log.d(TAG, "ssh: starting shell"); ByteArrayOutputStream responseStream = new ByteArrayOutputStream(); channel.setOut(responseStream); // open channel channel.open().verify(5, TimeUnit.SECONDS); // open channel channel.open().verify(5, TimeUnit.SECONDS); try (OutputStream pipedIn = channel.getInvertedIn()) { pipedIn.write(command.getBytes()); pipedIn.flush(); } // close channel channel.waitFor(EnumSet.of(ClientChannelEvent.CLOSED), TimeUnit.SECONDS.toMillis(5)); // output after converting to string type String responseString = responseStream.toString(); Log.d(TAG, "ssh: responseString == " + responseString); } catch (Exception e) { Log.d(TAG, "sshConnect(): client.connect(): Exception: " + e.toString()); e.printStackTrace(); } } catch (Exception e) { Log.d(TAG, "sshConnect(): client.start(): Exception: " + e.toString()); e.printStackTrace(); } }
解决方案
原因分析
Android SDK并未包含完整的Java EE类库,javax.management相关类属于Java EE范畴,Apache SSHD的部分版本会依赖这些类,导致在Android环境中找不到对应的类文件。
具体修复步骤
补充缺失的依赖类库
添加javax.management相关的API依赖到build.gradle中,直接引入适配的类库:implementation "javax.management:javax.management-api:1.3.2"升级Apache SSHD版本并优化依赖
旧版本的sshd-core(如2.1.0)对Android兼容性较差,建议升级到最新稳定版,同时移除重复依赖(sshd-common已被sshd-core包含,无需单独引入;新版本sshd不再依赖mina-core):dependencies { implementation "org.apache.sshd:sshd-core:3.10.0" implementation "org.apache.sshd:sshd-putty:3.10.0" implementation "org.slf4j:slf4j-api:2.0.9" implementation "org.slf4j:slf4j-simple:2.0.9" // 移除mina-core和sshd-common依赖 }启用Java API Desugaring(可选)
如果上述步骤仍无法解决问题,可在app/build.gradle中启用coreLibraryDesugaring,让Android支持更多Java标准库类:android { compileOptions { coreLibraryDesugaringEnabled true sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } } dependencies { coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4' }
内容的提问来源于stack exchange,提问作者user1933677
相关产品推荐
相关产品推荐

