FileTranslate Error Sloved
http://code.google.com/p/asmack/issues/detail?id=23
http://community.igniterealtime.org/message/201866#201866
Reported by un.v...@googlemail.com, Jun 16, 2010
Used code:
m_FTManager = new FileTransferManager(m_Connection);
produces:
E/AndroidRuntime( 8142): Caused by: java.lang.NullPointerException
E/AndroidRuntime( 8142): at org.jivesoftware.smackx.filetransfer.FileTransferNegotiator.setServiceEnabled(FileTransferNegotiator.java:126)
E/AndroidRuntime( 8142): at org.jivesoftware.smackx.filetransfer.FileTransferNegotiator.getInstanceFor(FileTransferNegotiator.java:107)
E/AndroidRuntime( 8142): at org.jivesoftware.smackx.filetransfer.FileTransferManager.<init>(FileTransferManager.java:63)
somehow there is no ServiceDiscoveryManager for my connection, which is why null is returned by ServiceDiscoveryManager.getInstanceFor().
Comment 1 by sgki...@gmail.com, Jul 18, 2010
With asmack-issue-13.jar, I can make FileTransferManager object, but it also failed to transfer file with service-unavailable error like this.
I'm testing with android client with asmack, OpenFire server for Windows, and Spark for Windows.
07-19 02:54:47.307: DEBUG/SMACK(228): 02:54:47 AM SENT (1135385920): <iq id="Gnn6w-26" to="test2@testmachine" from="test@testmachine/Smack" type="set"><si xmlns="http://jabber.org/protocol/si" id="jsi_9109545620352116371" profile="http://jabber.org/protocol/si/profile/file-transfer"><file xmlns="http://jabber.org/protocol/si/profile/file-transfer" name="forest.jpg" size="128068" ><desc>You won't believe this!</desc></file><feature xmlns="http://jabber.org/protocol/feature-neg"><x xmlns="jabber:x:data" type="form"><field var="stream-method" type="list-multi"><option><value>http://jabber.org/protocol/bytestreams</value></option><option><value>http://jabber.org/protocol/ibb</value></option></field></x></feature></si></iq>
07-19 02:54:47.410: DEBUG/SMACK(228): 02:54:47 AM RCV (1135385920): <iq type="error" id="Gnn6w-26" from="test2@testmachine" to="test@testmachine/Smack"><si xmlns="http://jabber.org/protocol/si" id="jsi_9109545620352116371" profile="http://jabber.org/protocol/si/profile/file-transfer"><file xmlns="http://jabber.org/protocol/si/profile/file-transfer" name="forest.jpg" size="128068"><desc>You won't believe this!</desc></file><feature xmlns="http://jabber.org/protocol/feature-neg"><x xmlns="jabber:x:data" type="form"><field var="stream-method" type="list-multi"><option><value>http://jabber.org/protocol/bytestreams</value></option><option><value>http://jabber.org/protocol/ibb</value></option></field></x></feature></si><error code="503" type="cancel"><service-unavailable xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/></error></iq>
Any ideas?
Comment 2 by sgki...@gmail.com, Jul 19, 2010
I have some more progress on this issue.
As the file transfer API document guided, I put a fully-qualified jabber ID consists of a node, a domain, and a resource, then I can see the file transfer view in Spark.
But I can see the following error, when I clicked 'accept' in Spark chat window.
Thread [<23> File Transfer jsi_2403365644062062677] (Suspended (exception ClassCastException))
FileTransferNegotiator.negotiateOutgoingTransfer(String, String, String, long, String, int) line: 401
OutgoingFileTransfer.negotiateStream(String, long, String) line: 359
OutgoingFileTransfer.access$100(OutgoingFileTransfer, String, long, String) line: 35
OutgoingFileTransfer$2.run() line: 214
Thread.run() line: 1096
There is no problem with sample application using Smack in windows.
Comment 3 by sgki...@gmail.com, Jul 19, 2010
When I added configure function as Mike showed in the link ( http://community.igniterealtime.org/message/201866#201866 ), ClassCastException error had gone, but the file transfer failed too.
Spark log shows there is error and I can't found any error log in Android side.
2010. 7. 20 오후 2:42:36 org.jivesoftware.spark.util.log.Log error
심각: There was an error during file transfer.
Error in execution:
-- caused by: java.util.concurrent.ExecutionException: File transfer negotiation failed.:
at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer.negotiateStream(IncomingFileTransfer.java:199)
at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer.access$100(IncomingFileTransfer.java:47)
at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer$1.run(IncomingFileTransfer.java:124)
at java.lang.Thread.run(Unknown Source)
Nested Exception:
java.util.concurrent.ExecutionException: File transfer negotiation failed.:
at java.util.concurrent.FutureTask$Sync.innerGet(Unknown Source)
at java.util.concurrent.FutureTask.get(Unknown Source)
at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer.negotiateStream(IncomingFileTransfer.java:193)
at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer.access$100(IncomingFileTransfer.java:47)
at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer$1.run(IncomingFileTransfer.java:124)
at java.lang.Thread.run(Unknown Source)
Caused by: File transfer negotiation failed.:
at org.jivesoftware.smackx.filetransfer.FaultTolerantNegotiator.createIncomingStream(FaultTolerantNegotiator.java:128)
at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer$2.call(IncomingFileTransfer.java:186)
at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer$2.call(IncomingFileTransfer.java:185)
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at org.jivesoftware.smackx.filetransfer.IncomingFileTransfer.negotiateStream(IncomingFileTransfer.java:190)
... 3 more
Comment 4 by sgki...@gmail.com, Jul 20, 2010
Eventually I succeeded to transfer file by disabling proxy support on OpenFire server. :)
Comment 5 by agnos....@gmail.com, Jul 21, 2010
I found a trick and finally fixed the problem by inserting the following code before instantiaging a FileTransferManager.
// you have to make a dummy service discovery manager.
new ServiceDiscoveryManager(your XMPP connection);
// now this line does not cause any problems.
mFileTransferManager = new FileTransferManager(your XMPP connection);
Even though the code removes the NullPointerException, there still exists a problem.
You will see "ClassCastException : PacketParserUtils$2" :(
I finally found the solution.
When you connect to XMPP server, SMACK API automatically loads the "META-INF/smack.providers" file and reads several packet processing providers. Android does not allow this, I guess this is a kind of security issue. Therefore, the code of Android SMACK API should be fixed.
Though this is a permanent remedy, you can successfully transfer a file with the following code snippet.
First, you have to copy a smack.properties to you android emulator.
You can get smack.properties at the original SMACK API site.
http://www.igniterealtime.org/downloads/source.jsp
For example, I pushed smack.properties into "/data/" folder.
After that, I modified initialize() method of ProviderManager.java (it's in org/jivesoftware/smack/provider) as follows.
Find the following line.
Enumeration providerEnum = classLoader.getResources(
"/META-INF/smack.providers");
Replace it with
Enumeration providerEnum = classLoader.getResources(
"/data/smack.providers");
I hope this helps.
Comment 6 by sgki...@gmail.com, Jul 21, 2010
Thank you for summarizing the procedure to fix the problem.
My way is almost same with yours. :)
Comment 7 by chandra....@gmail.com, Jul 31, 2010
Thank you for helping us to proceed.
Hi agnos.kim,
I am using asmack-2010.05.07-source in eclipse for android-2.2.
After adding your solution
<solution
Enumeration providerEnum = classLoader.getResources(
"/META-INF/smack.providers");
Replace it with -
Enumeration providerEnum = classLoader.getResources(
"/data/smack.providers");
/>
I am still getting the error
08-01 01:55:51.050: ERROR/AndroidRuntime(1649): java.lang.ClassCastException: org.jivesoftware.smack.util.PacketParserUtils$2
08-01 01:55:51.050: ERROR/AndroidRuntime(1649): at org.jivesoftware.smackx.filetransfer.FileTransferNegotiator.negotiateOutgoingTransfer(FileTransferNegotiator.java:401)
08-01 01:55:51.050: ERROR/AndroidRuntime(1649): at org.jivesoftware.smackx.filetransfer.OutgoingFileTransfer.negotiateStream(OutgoingFileTransfer.java:359)
08-01 01:55:51.050: ERROR/AndroidRuntime(1649): at org.jivesoftware.smackx.filetransfer.OutgoingFileTransfer.access$0(OutgoingFileTransfer.java:352)
08-01 01:55:51.050: ERROR/AndroidRuntime(1649): at org.jivesoftware.smackx.filetransfer.OutgoingFileTransfer$2.run(OutgoingFileTransfer.java:214)
08-01 01:55:51.050: ERROR/AndroidRuntime(1649): at java.lang.Thread.run(Thread.java:1096)
Please tell me what i am missing ...
Comment 8 by chandra....@gmail.com, Aug 1, 2010
Sorry i missed "Mike's fix showed in the link ( http://community.igniterealtime.org/message/201866#201866 ) "
Now it works.
Thank you very much for all your solutions.
All the best !!
Comment 9 by neha...@gmail.com, Oct 19, 2010
I don't get any of the above exceptions when I use asmack 15, but the file transfer just doesn't happen. I'm trying to take a picture on the phone, save it on the sdcard and then send it via xmpp. Everything in the logs (logcat) looks fine and I can see chat messages but no files. Any ideas?
Thanks,
Neha.
Comment 10 by TT0...@gmail.com, Jan 11, 2011
Today ,I succeeded to transfer file by Using“asmack-issue15.jar” & in android2.3 .
Thanks,
Chen Wen
Comment 11 by tur...@gmail.com, Jan 28, 2011
I am trying to send a file to a simple asmack client, but the packets seem to get lost somewhere. I've used a number of asmack builds (asmack-issue15, a rtreffer source build, etc.), but they all lead me to the same result. The stream negotiation works fine, but the actual transfer never seems to happen. I get the following debug output:
XMPPClient: status: Initial
XMPPClient: Progress: 0.0/10
XMPPClient: status: Negotiating Stream
XMPPClient: Progress: 0.0/10
XMPPClient: status: In Progress
XMPPClient: Progress: 0.0/10
XMPPClient: status: In Progress
XMPPClient: Progress: 0.0/10
XMPPClient: status: In Progress
XMPPClient: Progress: 0.0/10
... and continues indefinitely
The file sending dialog on the Tkabber client closes as though it successfully sent the file, but the android client keeps waiting.
I noticed that the inputStream in IncomingFileTransfer.receiveFile has a null buffer (and the writeToStream call blocks), which means that it never receives any packets. I don't get any exceptions or any other signs that something is wrong. Any help would be greatly appreciated!
Thank you,
Andrey
Comment 12 by moussaou...@gmail.com, Mar 12, 2011
Hello.
I am still getting the error
08-01 01:55:51.050: ERROR/AndroidRuntime(1649): java.lang.ClassCastException: org.jivesoftware.smack.util.PacketParserUtils$2
08-01 01:55:51.050: ERROR/AndroidRuntime(1649): at org.jivesoftware.smackx.filetransfer.FileTransferNegotiator.negotiateOutgoingTransfer(FileTransferNegotiator.java:401)
08-01 01:55:51.050: ERROR/AndroidRuntime(1649): at org.jivesoftware.smackx.filetransfer.OutgoingFileTransfer.negotiateStream(OutgoingFileTransfer.java:359)
08-01 01:55:51.050: ERROR/AndroidRuntime(1649): at org.jivesoftware.smackx.filetransfer.OutgoingFileTransfer.access$0(OutgoingFileTransfer.java:352)
08-01 01:55:51.050: ERROR/AndroidRuntime(1649): at org.jivesoftware.smackx.filetransfer.OutgoingFileTransfer$2.run(OutgoingFileTransfer.java:214)
08-01 01:55:51.050: ERROR/AndroidRuntime(1649): at java.lang.Thread.run(Thread.java:1096)
Where is the problem?
It's probably a problem of type of packets to send.
Shot in the dark - Smack API, Android SDK and ClassCastExceptions.
http://community.igniterealtime.org/message/201866#201866
I think this is a bit of a long shot but I figured I might as well give this a try.
So I'm using this patched version of the Smack API with the Google Phone Android SDK to try to get a custom client working on that platform. What I keep running into in different places are ClassCastExceptions when the API tries to cast Packets into subclasses.
Here's an example from the ServiceDiscoveryManager
PacketCollector collector =
connection.createPacketCollector(new PacketIDFilter(disco.getPacketID()));
connection.sendPacket(disco);
// Wait up to 5 seconds for a result.
IQ result = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
// Stop queuing results
collector.cancel();
if (result == null) {
Log.i("TestClient", "++++ No response from the server.");
}
if (result.getType() == IQ.Type.ERROR) {
Log.i("TestClient",result.getError().toString());
}
Log.i("TestClient", ">>>> \"" + result.getClass().getName()+"\"");
Packet test = (Packet) result;
Log.i("TestClient", "Result class loader: " + test.getClass().getClassLoader().toString());
Log.i("TestClient", "DI Class loader: " + DiscoverItems.class.getClassLoader().toString());
return (DiscoverItems) test;
the cast of the Packet to DiscoverItems will fail with a ClassCastException. As you can see from the Log statements in this case I've even made sure the Class loaders are the same and that the Class is the parent class. I can even successfully cast it to a Packet but not to a sub class.
Any help would be appreciated before I pull my hair out.
Thanks.
//-------------------------------------------------------------------------------------------------------------
2008-4-3 下午10:41 (回复 Mike Ryan)
Re: Shot in the dark - Smack API, Android SDK and ClassCastExceptions.
Ok so I've gotten a few questions about this so I guess I should really answer my own question
From what I can tell each provider has a static function that registers it with the provider manage this usually happens on class load but this isn't working with Android so none of the providers are getting registered with the provider manager. However you can do that manually. So I have a function like so:
You can call it with configure(ProviderManager.getInstance()) I do this before calling new XMPPConnection()
public void configure(ProviderManager pm) {
// Private Data Storage
pm.addIQProvider("query","jabber:iq:private", new PrivateDataManager.PrivateDataIQProvider());
// Time
try {
pm.addIQProvider("query","jabber:iq:time", Class.forName("org.jivesoftware.smackx.packet.Time"));
} catch (ClassNotFoundException e) {
Log.w("TestClient", "Can't load class for org.jivesoftware.smackx.packet.Time");
}
// Roster Exchange
pm.addExtensionProvider("x","jabber:x:roster", new RosterExchangeProvider());
// Message Events
pm.addExtensionProvider("x","jabber:x:event", new MessageEventProvider());
// Chat State
pm.addExtensionProvider("active","http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
pm.addExtensionProvider("composing","http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
pm.addExtensionProvider("paused","http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
pm.addExtensionProvider("inactive","http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
pm.addExtensionProvider("gone","http://jabber.org/protocol/chatstates", new ChatStateExtension.Provider());
// XHTML
pm.addExtensionProvider("html","http://jabber.org/protocol/xhtml-im", new XHTMLExtensionProvider());
// Group Chat Invitations
pm.addExtensionProvider("x","jabber:x:conference", new GroupChatInvitation.Provider());
// Service Discovery # Items
pm.addIQProvider("query","http://jabber.org/protocol/disco#items", new DiscoverItemsProvider());
// Service Discovery # Info
pm.addIQProvider("query","http://jabber.org/protocol/disco#info", new DiscoverInfoProvider());
// Data Forms
pm.addExtensionProvider("x","jabber:x:data", new DataFormProvider());
// MUC User
pm.addExtensionProvider("x","http://jabber.org/protocol/muc#user", new MUCUserProvider());
// MUC Admin
pm.addIQProvider("query","http://jabber.org/protocol/muc#admin", new MUCAdminProvider());
// MUC Owner
pm.addIQProvider("query","http://jabber.org/protocol/muc#owner", new MUCOwnerProvider());
// Delayed Delivery
pm.addExtensionProvider("x","jabber:x:delay", new DelayInformationProvider());
// Version
try {
pm.addIQProvider("query","jabber:iq:version", Class.forName("org.jivesoftware.smackx.packet.Version"));
} catch (ClassNotFoundException e) {
// Not sure what's happening here.
}
// VCard
pm.addIQProvider("vCard","vcard-temp", new VCardProvider());
// Offline Message Requests
pm.addIQProvider("offline","http://jabber.org/protocol/offline", new OfflineMessageRequest.Provider());
// Offline Message Indicator
pm.addExtensionProvider("offline","http://jabber.org/protocol/offline", new OfflineMessageInfo.Provider());
// Last Activity
pm.addIQProvider("query","jabber:iq:last", new LastActivity.Provider());
// User Search
pm.addIQProvider("query","jabber:iq:search", new UserSearch.Provider());
// SharedGroupsInfo
pm.addIQProvider("sharedgroup","http://www.jivesoftware.org/protocol/sharedgroup", new SharedGroupsInfo.Provider());
// JEP-33: Extended Stanza Addressing
pm.addExtensionProvider("addresses","http://jabber.org/protocol/address", new MultipleAddressesProvider());
// FileTransfer
pm.addIQProvider("si","http://jabber.org/protocol/si", new StreamInitiationProvider());
pm.addIQProvider("query","http://jabber.org/protocol/bytestreams", new BytestreamsProvider());
pm.addIQProvider("open","http://jabber.org/protocol/ibb", new IBBProviders.Open());
pm.addIQProvider("close","http://jabber.org/protocol/ibb", new IBBProviders.Close());
pm.addExtensionProvider("data","http://jabber.org/protocol/ibb", new IBBProviders.Data());
// Privacy
pm.addIQProvider("query","jabber:iq:privacy", new PrivacyProvider());
pm.addIQProvider("command", "http://jabber.org/protocol/commands", new AdHocCommandDataProvider());
pm.addExtensionProvider("malformed-action", "http://jabber.org/protocol/commands", new AdHocCommandDataProvider.MalformedActionError());
pm.addExtensionProvider("bad-locale", "http://jabber.org/protocol/commands", new AdHocCommandDataProvider.BadLocaleError());
pm.addExtensionProvider("bad-payload", "http://jabber.org/protocol/commands", new AdHocCommandDataProvider.BadPayloadError());
pm.addExtensionProvider("bad-sessionid", "http://jabber.org/protocol/commands", new AdHocCommandDataProvider.BadSessionIDError());
pm.addExtensionProvider("session-expired", "http://jabber.org/protocol/commands", new AdHocCommandDataProvider.SessionExpiredError());
}
Ah sorry about that the AdHoc Command was actually something I specifically needed and I found somewhere out on the nets! So I'm actually building and patching my own Smack Jar.
If you need it let me know I can fill you in.
· ---------------------------------------------------------------------------------------------------------------------------------------
Thanks for the clarification. I wasn't sure why that was happening. I did findhttp://community.igniterealtime.org/docs/DOC-1945 earlier, but I've yet to try this. Anyone tried this yet?
I'll give it a shot in the next few days and report back.
§ 有用回答Re: Android: How to avoid ClassCastException: org.jivesoftware.smack.util. PacketParserUtils$2 ?
That is meant to solve a different issue. In a normal java environment, the smack.providers file is on the classpath by default as it is containted in the smackx.jar. I suspect that the Android classloader doesn't work the same way.
§ Android: How to avoid ClassCastException: org.jivesoftware. smack.util.PacketParser Utils$2 ?
I know what you mean. However, for now, and to get it to run properly on Android, I added a method to ProviderManager to load this from an external file. Then I recompiled the JARs and put smack.providers on the phone's SD card. Before making a connection, I load the smack providers from that file and it seems to work fine. Not the best approach, but it works.
Thanks for your comments!