javaxmppopenfiresmack

Smack FileTransferManager.addFileTransferListener is never called


I 'm developing a standalone Java test application using smack 4.3.4. I use In-Band for file transfers:

FileTransferManager fileTransferManager = FileTransferManager.getInstanceFor(connection);
        FileTransferNegotiator.IBB_ONLY = true;
        OutgoingFileTransfer fileTransfer = null;
        try {
            fileTransfer = fileTransferManager.createOutgoingFileTransfer(JidCreate.entityFullFrom(buddyJID + "/Spark"));
        } catch (XmppStringprepException ex) {
            LOG.log(Level.SEVERE, null, ex);
        }
       if (fileTransfer != null) {
            OutgoingFileTransfer.setResponseTimeout(500);
            ...
           try {
                    fileTransfer.sendFile(file, "sending attachment...");
                } catch (SmackException ex) {
                    LOG.log(Level.SEVERE, null, ex);
                }
           ...

I monitor the file transfer and it is sent correctly.

INFO: Initializing connection to server localhost port 5222 [Wed Apr 29 15:36:25 CEST 2020]
INFO: Connected: true [Wed Apr 29 15:36:45 CEST 2020]
INFO: user001 authenticated? true [Wed Apr 29 15:36:46 CEST 2020]
...
INFO: Sending attachment 'test.txt' to user user002@localhost [Wed Apr 29 15:36:55 CEST 2020]
INFO: status is:Initial [Wed Apr 29 15:36:55 CEST 2020]
INFO: status is:Initial [Wed Apr 29 15:36:55 CEST 2020]
INFO: File transfer status: Negotiating Transfer, progress: 0.0 [Wed Apr 29 15:36:55 CEST 2020]
INFO: test.txt has been successfully transferred. [Wed Apr 29 15:36:56 CEST 2020]
INFO: The file transfer is done. [Wed Apr 29 15:36:56 CEST 2020]
INFO: Attachment test.txt sent from user001@localhost to user002@localhost [Wed Apr 29 15:36:56 CEST 2020]

When my user(s) connect and login to Openfire, even before the start sending attachments, I add a listener to listen to file transfers:

final FileTransferManager manager = FileTransferManager.getInstanceFor(connection);
//        FileTransferNegotiator.setServiceEnabled(connection, true);   
        manager.addFileTransferListener((FileTransferRequest request) -> {
            // Check to see if the request should be accepted
            if (request.getFileName() != null) {
                try {
                    // Accept it
                    IncomingFileTransfer transfer = request.accept();
//                    monitorFileTransfer(transfer, "");
                    try (InputStream fileReceived = transfer.receiveFile();
                            BufferedInputStream bis = new BufferedInputStream(fileReceived)) {
                    ...
              } else {
                try {
                    // Reject it
                    request.reject();
                    LOG.warning("File rejected " + request.getFileName());
                } catch (SmackException.NotConnectedException | InterruptedException ex) {
                    LOG.log(Level.SEVERE, null, ex);
                }
            }

However, the listener is never called. Do I need to add the listener at a specific moment? Is there something else I 've been missing? The results is that the file transfers are being sent to Openfire and are never consumed.

Last stanzas:

<iq xmlns="jabber:client" to="user001@localhost/aktuu2n806" from="localhost" id="679-1085" type="get">
  <query xmlns="jabber:iq:version"/>
</iq>
<iq xmlns="jabber:client" to="localhost" id="679-1085" type="error">
  <error xmlns="jabber:client" type="modify">
    <not-acceptable xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
  </error>
</iq>

My code is based on the documentation example. Do I need to configure something else? Since they are transferred as in-band I shouldn't.

Thank you in advance for your prompt reply.


Solution

  • The file transfer was not actually happening this is why the listener was listening but wa receiving nothing.

    To send a file you need the full JID of the recipient. If you use smack, there is no physical XMPP client (like spark). In that case you use “Smack” or “Resource” (see here).

    fileTransfer = fileTransferManager.createOutgoingFileTransfer(JidCreate.entityFullFrom(buddyJID + "/Smack")));
    

    However, I still get an error:

    XMPP error reply received from user002@localhost/Smack: XMPPError: not-allowed - cancel
    

    and the file is not sent.

    UPDATE: And of course the problem had nothing to do with smack. The issue was that the tool I have created was reading and writing to the same file, as a result, the file was erased and the error was because smack was requested to transfer an empty file. So, if you see this error, check the file you try to transfer first; it might have 0 bytes.