DreamSea

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::


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.

 //-------------------------------------------------------------------------------------------------------------

Mike Ryan 

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!

posted on 2011-07-28 09:45  DreamSea  阅读(2073)  评论(0编辑  收藏  举报