Weird connection dropping problem

HI,

I’'m trying to write a simple Java based Jabber client to send and receive messages from a Jive Messenger server.

I can send a message fine but the connection always gets closed directly after I send the message. Any ideas why this might be the case? I get the following error from the Connection Listener:

java.io.EOFException - no more data available

Here is my code:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader; import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ConnectionListener;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet; public class chatApp {
     static XMPPConnection con = null;
     static Chat chat = null;
     
     public static void main(String[] args) {
          try{
               connect();
               
               if(con.isConnected()){
                    System.out.println("Connected");
               }
               System.out.println("Logging into Server");
               
               con.login("john", "Atunas21");
               
               if(con.isAuthenticated()){
                    System.out.println("authenticated");
               }
                              
               
               Chat chat = con.createChat("andrea@monomoy.homelinux.com");
                              
               chat.addMessageListener(new PacketListener() {
                    
                    public void processPacket(Packet arg0) {
                         System.out.println("Msg received: "+ arg0.toString());
                    }
               });
               
               Message newMessage = chat.createMessage();
               newMessage.setBody("Howdy!");
               chat.sendMessage(newMessage);     
               
               BufferedReader in = new BufferedReader(new InputStreamReader(System.in));                       String input;                       System.out.println("Enter ''quit!'' to quit.");
               boolean bWait = true;
               while (bWait) {                                if ((input = in.readLine()).equals("quit!")) {                                         System.out.println("Quitting");                           bWait = false;
                         con.close();
                         con = null;
                         System.gc();
                         System.exit(0);
                    } else{
                         System.out.println("Sending Message");
                         chat.sendMessage(input);
                    }
                    // Wait for the next message the user types to us.
                    Message message = chat.nextMessage();
                    System.out.println(message.getBody());                                                }
          }catch(XMPPException xe){
               System.out.println(xe.toString()+ ": " + xe.getMessage());
               xe.printStackTrace();
               if(con != null && con.isConnected()){
                    con.close();
               }
          }catch(IOException xe){
               System.out.println(xe.toString()+ ": " + xe.getMessage());
               xe.printStackTrace();
               if(con != null && con.isConnected()){
                    con.close();
               }
          }catch(Exception xe){
               System.out.println(xe.toString()+ ": " + xe.getMessage());
               xe.printStackTrace();
               if(con != null && con.isConnected()){
                    con.close();
               }
          }finally{
               if(con != null && con.isConnected()){
                    con.close();
               }
          }          
     }
     
     public static void connect(){
          try{
               System.out.println("Connecting to Jive Server");
               XMPPConnection.DEBUG_ENABLED = true;
               con = new XMPPConnection("monomoy.homelinux.com");
               con.addConnectionListener(new ConnectionListener(){
                    public void connectionClosed(){
                         System.out.println("Connection has been closed");
                         reconnect();
                         
                    }
                    public void connectionClosedOnError(Exception ex){
                         System.out.println("Connection has been closed because of: "                               + ex.toString() + ": "+ ex.getMessage());
                         reconnect();
                    }
               });
          }catch(XMPPException xe){
               System.out.println(xe.toString()+ ": " + xe.getMessage());
               xe.printStackTrace();
               if(con != null && con.isConnected()){
                    con.close();
               }
          }
     }
     
     public static void reconnect(){
          try{
               boolean bReconnect = false;
               if(bReconnect){
                    System.out.println("Connecting to Jive Server");
                    XMPPConnection.DEBUG_ENABLED = true;
                    con = new XMPPConnection("monomoy.homelinux.com");
                    con.addConnectionListener(new ConnectionListener(){
                    
                         public void connectionClosed(){
                              System.out.println("Connection has been closed");
                              reconnect();                         
                         }
                         public void connectionClosedOnError(Exception ex){
                              System.out.println("Connection has been closed because of: "                                    + ex.toString() + ": "+ ex.getMessage());
                              reconnect();
                         }
                    });
               }
          }catch(XMPPException xe){
               System.out.println(xe.toString()+ ": " + xe.getMessage());
               xe.printStackTrace();
               if(con != null && con.isConnected()){
                    con.close();
               }
          }
     }
}

What is the exact error that you’'re getting?

Regards,

Matt

Hi Matt,

Thanks for formatting the code!

So the error I catch is from inside the connection listener:

java.io.EOFException: no more data available

at org.xmlpull.mxp1.MXParser.fillBuf(MXParser.java:2968)

at org.xmlpull.mxp1.MXParser.more(MXParser.java:2975)

at org.xmlpull.mxp1.MXParser.nextImpl(MXParser.java:1188)

at org.xmlpull.mxp1.MXParser.next(MXParser.java:1137)

at org.jivesoftware.smack.PacketReader.parsePackets(PacketReader.java:310)

at org.jivesoftware.smack.PacketReader.access$000(PacketReader.java:77)

at org.jivesoftware.smack.PacketReader$1.run(PacketReader.java:103)

The messages I get from the debug frame are :

SENT:

<stream:stream to=“monomoy.homelinux.com” xmlns=“jabber:client” xmlns:stream=“http://etherx.jabber.org/streams”>

john

john73fd618c1642e87f84c7654 22a33ee400d1fcb03Smack

</stream:stream>

RECEIVED:

<stream:stream xmlns=’‘jabber:client’’ xmlns:stream=’‘http://etherx.jabber.org/streams’’ from=’‘monomoy.homelinux.com’’ id=’‘b24166cc’’>

    <item jid="andrea@monomoy.homelinux.com" subscription="from"/>

INTERPRETED:

I also get the following in the Messenger Server error log:

2004.01.25 17:38 [com.jivesoftware.xmpp.spi.BasicChannel$ChannelWorker.run(BasicChannel.java:362 )

] Internal server error

java.lang.NullPointerException

at com.jivesoftware.xmpp.spi.PresenceManagerImpl.probePresence(PresenceManagerImpl .java:326)

at com.jivesoftware.xmpp.handler.IQRosterHandler.manageRoster(IQRosterHandler.java :166)

at com.jivesoftware.xmpp.handler.IQRosterHandler.handleIQ(IQRosterHandler.java:97)

at com.jivesoftware.xmpp.spi.IQHandler.handleMessages(IQHandler.java:48)

at com.jivesoftware.xmpp.spi.BasicChannel$ChannelWorker.run(BasicChannel.java:340)

AND in the Info log

2004.01.25 17:38 Connect Socket[addr=/65.96.191.208,port=60210,localport=5222]

2004.01.25 17:38 john@monomoy.homelinux.com/Smack authenticated on connection com.jivesoftware.xmpp.net.SocketConnection@15ad5c6

2004.01.25 17:38 Logging off john@monomoy.homelinux.com/Smack on com.jivesoftware.xmpp.net.SocketConnection@15ad5c6

Hi,

What version of Messenger are you using, and what database is Messenger using? If you’‘re using the embedded database, can you try to use it against MySQL or another external database? If you’‘re using an external database, can you do a ‘‘select * from jiveRoster’’ (assuming your Messenger install only contains the two users you’'re testing against).

Your client code looks OK. I think your roster is in a weird state which is causing the server to boot your connection during login.

Thanks

-iain

Here is the output from the Roster query. It looks like there are multiple entries for some users, ie I see different rosterIDs for the same userID eg userID 2, brian@monomoypartners.com has a rosterID of 10 and 11. Is this normal? If not, how should I fix it?

mysql> select * from jiveRoster;

*----


*–


+


+-+-++-----+

rosterID

userID

jid

sub

ask

recv

nick

*----


*–


+


+-+-++-----+

9

2

andrea@monomoy.homelinux.com

2

-1

-1

NULL

8

3

john@monomoy.homelinux.com

1

-1

-1

john

10

2

brian@monomoy.homelinux.com

0

0

-1

NULL

11

2

brian@monomoy.homelinux.com

0

-1

-1

brian

12

4

john@monomoy.homelinux.com

0

-1

1

NULL

13

2

monomoy.homelinux.com

2

0

-1

NULL

14

2

monomoy.homelinux.com

0

-1

-1

NULL

15

2

john@monomoy.homelinux.com

3

-1

-1

NULL

16

2

john@monomoy.homelinux.com

0

-1

-1

NULL

*----


*–


+


+-+-++-----+

9 rows in set (0.00 sec)

Also, I should mention that I’'ve been able to connect to the Server fine with Gaim, Psi and also my own client written using the Muse API. Perhaps Smack performs more dilligence than these? Not a bad thing by any means…

Iain,

Did you have any further thoughts about this problem?

Thanks

John

John,

We’'re still working on debugging the problem and will post further details as soon as we have an update.

Thanks,

Matt

Hi,

There looks like two things going on. First, there is a bug in Messenger causing your connection from being dropped. I’‘ve got a fix coded and it will be included in the Messenger 1.1 release (which will be very soon). Second, there does appear to be a strange set of roster entries in your database. I’‘m guessing you’‘re experimenting with roster support in Smack or you’‘re not using presence subscription packets according to the protocol. The smack code you posted doesn’‘t look like it should be causing a problem so I’'m guessing it was something you were experimenting with earlier?

The cleanest method to reset is to delete all the records associated with user 2. All the weird roster entries are associated with user 2 so I’‘m guessing that was the user account you were using to experiment with? If you can reproduce the steps you took to create those weird entries (e.g. drop the records, and try to do whatever you did earlier to recreate them) i’'d appreciate it. Messenger should be defending itself from misuse of the protocol and it apparently is not.

I’‘d also really like to know what version of Messenger you’'re using. There are a few roster related bugs that were present in the earlier versions of Messenger but have been fixed in more recent versions.

Thanks

-iain

Oh, and to answer your other question about why other clients don’‘t have a problem, smack actually provides more flexibility in what you can do - to the point where it will let you do nonstandard things if you want to. The flexibility exists so you can code new custom protocols on top of XMPP. Unfortunately it’'s enough rope to hang yourself in some cases.

-iain

Matt and Iain,

Thanks guys, great turnaround on this. I’‘ll test it tonight and let you know tomorrow what I find. I have a sneaking suspicion that it has to do with how Gaim or Psi were dealing with buddy lists. I haven’‘t tried messing around with Rosters directly so I don’'t think it was something I had tried. I remember having an error at one stage while adding users to buddy lists with either Gaim or Psi.

By the way Iain, great job on the book, any chance of a revised edition using Smack?

Cheers,

John

Sorry, forgot to give you the version. I believe that it’'s 1.0.8. At least the download was called ‘‘jive_messenger_win_jre_1_0_8.exe’’

Thanks again.

John

Hi John,

Thanks for the kind comments on the book. If there is a future edition it will definitely use Smack!

Also, thanks for the version info. Looks like it can’'t be chalked up to a resolved issue. The messenger 1.1 release did a lot of cleanup work on roster support and has been more stable than the 1.0.x roster implementation.

-iain

Well, I cleaned up the roster and that seemed to solve the problem. I’‘ve been able to connect using a standalone client. I’‘ve also been able to create a Struts based application to perform messaging and it works really well. Have you guys looked into this and if so, any suggestions, best practices for web-based jabber clients? Obviously things like using a new connection for each request are a bad idea but I’'m just curious if you have a best practices doc or page?

Thanks again for all you help,

John.

Iain,

Where can I find the 1.1 release? I don’'t see it on the download page. Is it available yet?

Where can I find the 1.1 release? I don’'t see it on

the download page. Is it available yet?

We hope to have 1.1 out by the end of the week.

Regards,

Matt

As for using it in a webclient, you should check around this forums for other related threads. The use of Smack in servlets has been discussed several times. I suggest you start another thread specifically on it. I think it would be great to form a group of people who are using Smack in servlets and come up with some best practices documents!

-iain