How to properly use smbj to connect and list files on a samba share in Android java?

5.5k Views Asked by At

When I connect with smbj, error log shows:

...
I/c.h.s.c.Connection: Successfully authenticated user on 192.168.1.222, session is 4399187361905
I/c.h.s.s.Session: Logging off session 4399187361905 from host 192.168.1.222
I/c.h.s.t.PacketReader: Thread[Packet Reader for 192.168.1.222,5,main] stopped.
I/c.h.s.c.Connection: Closed connection to 192.168.1.222
I/c.h.s.s.Session: Connecting to \\192.168.1.222\pop on session 4399187361905

Immediately - without any delay. So the connection is closed immediately after it is opened and it will them crash if I try to list files...

Caused by: com.hierynomus.smbj.common.SMBRuntimeException: com.hierynomus.protocol.transport.TransportException: Cannot write SMB2_TREE_CONNECT with message id << 4 >> as transport is disconnected

Which seems obvious since there's no open connection.

A question, related to smbj, indicated there was a problem with the way that person used the try statement... I believe this is a similar case.

Within an AsyncTask, I have:

try (Connection connection = client.connect(serverName)) {
    AuthenticationContext ac = new AuthenticationContext(username, password.toCharArray(), domain);
    Session session = connection.authenticate(ac);
    this.session = session;
    return session;
} catch (IOException e) {
    e.printStackTrace();
}

I'm certain there's a problem with the try-catch. Can someone please give a complete piece of code including the AsyncTask - as the smbj module github should have. I hope this will solve most issues for all users.

1

There are 1 best solutions below

0
On BEST ANSWER

You are using a try-with resource block. A try-with-resource block automatically executes close() on the variable that has been initialized in it's head (the head is Connection connection = client.connect(serverName)). In your case it is calling connection.close() when its is reaching the end of the try block when it reaches the return statement.

If you want to make the connection persistent move the initialization block inside the try-catch block:

try {
    Connection connection = client.connect(serverName);
    this.connection = connection; // save the connection reference to be able to close it later manually
    AuthenticationContext ac = new AuthenticationContext(username, password.toCharArray(), domain);
    Session session = connection.authenticate(ac);
    this.session = session;
    return session;
} catch (IOException e) {
    e.printStackTrace();
}

Of course you should not forget to manually call connection.close() when you want to close the connection. Therefore you should also save the reference to the created connection somewhere, not only the session.