Hi guys,
We’ve been working on file transfer for SIP Communicator lately and have been using the corresponding features from smack. Most of the
time the lib is doing a really nice job, so thank you guys for your work! Smack is really one fine piece of software!
We did come across a few minor problems though so we thought we’d share them here.
Sometimes, after sending a SI request and after the receiver accepts it, the negotiation would fail in the following way:
The FaultTolerantNegotiator on the receiving side creates the following initiation accept packet :
<iq id="6j5Lo-10" to="yana_stamcheva@jabber.org/sip-comm" from="yana.stamcheva@jabber.org/sip-comm" type="result">
<si xmlns="http://jabber.org/protocol/si">
<feature xmlns="http://jabber.org/protocol/feature-neg">
<x xmlns="jabber:x:data" type="submit">
<field var="stream-method">
<value>http://jabber.org/protocol/bytestreams</value>
<value>http://jabber.org/protocol/ibb</value>
</field>
</x>
</feature>
</si>
</iq>
The PacketCollector on the sending side (in FileTransferNegotiator.negotiateOutgoingTransfer()) gets the following packet:
<iq id="6j5Lo-10" to="yana_stamcheva@jabber.org/sip-comm" from="yana.stamcheva@jabber.org/sip-comm" type="result"></iq>
This however results in a ClassCastException, because smack expects a StreamInitiation packet instead. Here’s the corresponding code:
public StreamNegotiator negotiateOutgoingTransfer(final String userID, final String streamID, final String fileName, final long size, final String desc, int responseTimeout) throws XMPPException {
.... if (iqResponse.getType().equals(IQ.Type.RESULT)) {
StreamInitiation response = (StreamInitiation) siResponse;
.... }
}
And here is the exception we get: java.lang.ClassCastException: org.jivesoftware.smack.PacketReader$4:
java.lang.ClassCastException: org.jivesoftware.smack.PacketReader$4
[java] at org.jivesoftware.smackx.filetransfer.FileTransferNegotiator.negotiateOutgoingTransfer(FileTransferNegotiator.java:402)
[java] at org.jivesoftware.smackx.filetransfer.OutgoingFileTransfer.negotiateStream(OutgoingFileTransfer.java:359)
[java] at org.jivesoftware.smackx.filetransfer.OutgoingFileTransfer.access$100(OutgoingFileTransfer.java:35)
[java] at org.jivesoftware.smackx.filetransfer.OutgoingFileTransfer$2.run(OutgoingFileTransfer.java:214)
[java] at java.lang.Thread.run(Thread.java:613)
At that point the receiver would also get the following exception :
[java] Error in execution: [java] -- caused by: java.util.concurrent.ExecutionException: [java] -- caused by: No response from remote client: [java] at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer.negotiateStream(IncomingFileTransfer.java:199)
[java] at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer.access$100(IncomingFileTransfer.java:47)
[java] at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer$1.run(IncomingFileTransfer.java:124)
[java] at java.lang.Thread.run(Thread.java:613)
[java] Nested Exception: [java] java.util.concurrent.ExecutionException: [java] -- caused by: No response from remote client: [java] at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:215)
[java] at java.util.concurrent.FutureTask.get(FutureTask.java:85)
[java] at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer.negotiateStream(IncomingFileTransfer.java:193)
[java] at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer.access$100(IncomingFileTransfer.java:47)
[java] at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer$1.run(IncomingFileTransfer.java:124)
[java] at java.lang.Thread.run(Thread.java:613)
[java] Caused by: [java] -- caused by: No response from remote client: [java] at org.jivesoftware.smackx.filetransfer.FaultTolerantNegotiator.createIncomingStream(FaultTolerantNegotiator.java:115)
[java] at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer$2.call(IncomingFileTransfer.java:186)
[java] at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer$2.call(IncomingFileTransfer.java:185)
[java] at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:269)
[java] at java.util.concurrent.FutureTask.run(FutureTask.java:123)
[java] at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer.negotiateStream(IncomingFileTransfer.java:190)
[java] ... 3 more
I’d appreciate some advice here as to what would be the proper way to fix this.
On a completely different note, we are also experiencing some other problems with Jabber.org’s ejabberd. Attempts to initiate a file transfer would sometimes fail because the server would respond with a feature-not-implemented error.
feature-not-implemented(501)
[java] at org.jivesoftware.smackx.filetransfer.FileTransferNegotiator.negotiateOutgoingTransfer(FileTransferNegotiator.java:407)
[java] at org.jivesoftware.smackx.filetransfer.OutgoingFileTransfer.negotiateStream(OutgoingFileTransfer.java:359)
[java] at org.jivesoftware.smackx.filetransfer.OutgoingFileTransfer.access$100(OutgoingFileTransfer.java:35)
[java] at org.jivesoftware.smackx.filetransfer.OutgoingFileTransfer$2.run(OutgoingFileTransfer.java:214)
[java] at java.lang.Thread.run(Thread.java:613)
We don’t think this is a problem with smack (we witnessed similar behavior with Adium) but we thought we’d mention it anyway in case someone here would have an explanation.
Cheers
Yana