Search code examples
javaandroidapache-sshd

Apache SSHD throwing exception for lack of defined user home directory


I get the following stack trace..

FATAL EXCEPTION: main
Process: com.example.atest, PID: 22330
java.lang.ExceptionInInitializerError
    at org.apache.sshd.common.config.keys.IdentityUtils.getUserHomeFolder(IdentityUtils.java:66)
    at org.apache.sshd.common.config.keys.PublicKeyEntry$LazyDefaultKeysFolderHolder.<clinit>(PublicKeyEntry.java:501)
    at org.apache.sshd.common.config.keys.PublicKeyEntry.getDefaultKeysFolderPath(PublicKeyEntry.java:514)
    at org.apache.sshd.client.config.hosts.HostConfigEntry$LazyDefaultConfigFileHolder.<clinit>(HostConfigEntry.java:108)
    at org.apache.sshd.client.config.hosts.HostConfigEntry.getDefaultHostConfigFile(HostConfigEntry.java:1151)
    at org.apache.sshd.client.config.hosts.DefaultConfigFileHostEntryResolver.<init>(DefaultConfigFileHostEntryResolver.java:49)
    at org.apache.sshd.client.config.hosts.DefaultConfigFileHostEntryResolver.<clinit>(DefaultConfigFileHostEntryResolver.java:39)
    at org.apache.sshd.client.ClientBuilder.<clinit>(ClientBuilder.java:106)
    at org.apache.sshd.client.SshClient.setUpDefaultClient(SshClient.java:778)
    at com.example.atest.MainActivity.sshConnection(MainActivity.java:364)
    at com.example.atest.MainActivity.onResults(MainActivity.java:329)
    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.IllegalArgumentException: No user home
    at org.apache.sshd.common.util.ValidateUtils.$r8$lambda$9swTO1FsdJCT_rq3b8lw5Edwaiw(Unknown Source:2)
    at org.apache.sshd.common.util.ValidateUtils$$ExternalSyntheticLambda0.apply(D8$$SyntheticClass:0)
    at org.apache.sshd.common.util.ValidateUtils.createFormattedException(ValidateUtils.java:213)
    at org.apache.sshd.common.util.ValidateUtils.throwIllegalArgumentException(ValidateUtils.java:179)
    at org.apache.sshd.common.util.ValidateUtils.checkTrue(ValidateUtils.java:156)
    at org.apache.sshd.common.util.ValidateUtils.checkNotNullAndNotEmpty(ValidateUtils.java:56)
    at org.apache.sshd.common.config.keys.IdentityUtils$LazyDefaultUserHomeFolderHolder.<clinit>(IdentityUtils.java:52)
    at org.apache.sshd.common.config.keys.IdentityUtils.getUserHomeFolder(IdentityUtils.java:66) 
    at org.apache.sshd.common.config.keys.PublicKeyEntry$LazyDefaultKeysFolderHolder.<clinit>(PublicKeyEntry.java:501) 
    at org.apache.sshd.common.config.keys.PublicKeyEntry.getDefaultKeysFolderPath(PublicKeyEntry.java:514) 
    at org.apache.sshd.client.config.hosts.HostConfigEntry$LazyDefaultConfigFileHolder.<clinit>(HostConfigEntry.java:108) 
    at org.apache.sshd.client.config.hosts.HostConfigEntry.getDefaultHostConfigFile(HostConfigEntry.java:1151) 
    at org.apache.sshd.client.config.hosts.DefaultConfigFileHostEntryResolver.<init>(DefaultConfigFileHostEntryResolver.java:49) 
    at org.apache.sshd.client.config.hosts.DefaultConfigFileHostEntryResolver.<clinit>(DefaultConfigFileHostEntryResolver.java:39) 
    at org.apache.sshd.client.ClientBuilder.<clinit>(ClientBuilder.java:106) 
    at org.apache.sshd.client.SshClient.setUpDefaultClient(SshClient.java:778) 
    at com.example.atest.MainActivity.sshConnection(MainActivity.java:364) 
    at com.example.atest.MainActivity.onResults(MainActivity.java:329) 
    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) 

I think it is from following code in the sshd library..

@SuppressWarnings("synthetic-access")
public static Path getUserHomeFolder() {
    return LazyDefaultUserHomeFolderHolder.PATH;
}

I assume it is trying to get the user home directory on the Android device while initializing the ssh connection.

My app/build.gradle..

dependencies {

    implementation libs.sshd.core

My ssh method..

private static void sshConnection(String username, String password, String host, int port, long defaultTimeoutSeconds, String command) throws IOException {
    
SshClient client = SshClient.setUpDefaultClient();
client.start();

try (ClientSession session = client.connect(username, host, port)
        .verify(defaultTimeoutSeconds, TimeUnit.SECONDS).getSession()) {
    session.addPasswordIdentity(password);
    session.auth().verify(defaultTimeoutSeconds, TimeUnit.SECONDS);

    try (ByteArrayOutputStream responseStream = new ByteArrayOutputStream();
             ClientChannel channel = session.createChannel(Channel.CHANNEL_SHELL)) {
        channel.setOut(responseStream);
        try {
            channel.open().verify(defaultTimeoutSeconds, TimeUnit.SECONDS);
            try (OutputStream pipedIn = channel.getInvertedIn()) {
                pipedIn.write(command.getBytes());
                pipedIn.flush();
            }

            channel.waitFor(EnumSet.of(ClientChannelEvent.CLOSED),
                    TimeUnit.SECONDS.toMillis(defaultTimeoutSeconds));
            String responseString = new String(responseStream.toByteArray());
            //System.out.println(responseString);
            Log.d(TAG,responseString);
        } finally {
            channel.close(false);
        }
    }
} finally {
    client.stop();
}

}

Which home directory is sshd library trying to define, and how can I define it?


Solution

  • Android doesn't set the "user.home" property by default. I defined it in the onCreate() method to resolve the exception..

    System.setProperty("user.home", this.getApplicationInfo().dataDir);