powered by Jive Software

Bug Issue / How to report bugs?

Hi,

I haven’‘t been able to figure out how to register myself at JIRA. When clicking on register I just get a page saying who does administrate JIRA?! I also wasn’‘t able to post a bug report, but I believe that is because I haven’'t been logged on.

Aynway, I have the following issue with 1.3.0. In PacketWriter.sendPacket() queue.notify() is called instead of queue.notifyAll().

The following test cases (two classes ;-( ) will show the difference. Problem is, it works with jabberd, not with jive messenger.

package test.smack;

import java.util.Iterator;

import junit.framework.TestCase;

import org.jivesoftware.smack.*;

import tools.CreateUsers;

public class RemoveGroupTest extends TestCase {

public void setUp() throws XMPPException {

CreateUsers.removeUsers();

CreateUsers.createUsers();

CreateUsers.addBuddies();

}

public void testRemoveGroupTests() throws Exception {

System.out.println(">>>>1");

CreateUsers.dumpUsers();

System.out.println("<<<<1");

XMPPConnection connection = new XMPPConnection(CreateUsers.HOST);

connection.login(CreateUsers.USER_NAMES[0], CreateUsers.PASSWORD);

Roster roster = connection.getRoster();

String groupName = CreateUsers.GROUPS_NAMES[0];

RosterGroup group = roster.getGroup(groupName);

assertTrue(“Group " + groupName + " doesn’'t exists.”, group != null);

Iterator allUsers = group.getEntries();

while (allUsers.hasNext()) {

RosterEntry rosterEntry = (RosterEntry) allUsers.next();

group.removeEntry(rosterEntry);

}

// Thread.sleep(4000);

connection.close();

System.out.println(">>>>2");

CreateUsers.dumpUsers();

System.out.println("<<<<2");

connection = new XMPPConnection(CreateUsers.HOST);

connection.login(CreateUsers.USER_NAMES[0], CreateUsers.PASSWORD);

roster = connection.getRoster();

groupName = CreateUsers.GROUPS_NAMES[0];

group = roster.getGroup(groupName);

assertTrue(“Group " + groupName + " exists.”, group == null);

//assertTrue(“Number of entries of Group “+groupName +” != 0.” , group.getEntryCount() == 0);

connection.close();

}

}

package tools;

import java.util.Iterator;

import org.jivesoftware.smack.*;

public class CreateUsers {

public static final String HOST = “localhost”;

public static final String[] USER_NAMES = new String[] { “one”, “two”};

public static final String[] GROUPS_NAMES = new String[] { “First”, “Second”, “Third”};

public static final String PASSWORD = “password”;

public static void main(String[] args) throws Exception {

System.out.println(“Started.”);

removeUsers();

createUsers();

addBuddies();

dumpUsers();

System.out.println(“Done.”);

}

public static void removeUsers() {

for (int i = 0; i < USER_NAMES.length; i++) {

String username = USER_NAMES+;

try {

System.out.print("Deleting " + username + ": ");

XMPPConnection connection = new XMPPConnection(HOST);

connection.login(username, PASSWORD);

connection.getAccountManager().deleteAccount();

connection.close();

System.out.println(“done.”);

} catch (Exception e) {

e.printStackTrace();

}

}

}

public static void dumpUsers() {

for (int i = 0; i < USER_NAMES.length; i++) {

String username = USER_NAMES+;

try {

System.out.println("Dumping " + username + ": ");

XMPPConnection connection = new XMPPConnection(HOST);

connection.login(username, PASSWORD);

Roster roster = connection.getRoster();

Iterator allEntries = roster.getEntries();

while (allEntries.hasNext()) {

RosterEntry rosterEntry = (RosterEntry) allEntries.next();

System.out.println(“name=” + rosterEntry.getName());

System.out.println(“user=” + rosterEntry.getUser());

Iterator allGroups = rosterEntry.getGroups();

while (allGroups.hasNext()) {

RosterGroup rosterGroup = (RosterGroup) allGroups.next();

System.out.println(“groupName=” + rosterGroup.getName() + “, " + rosterGroup.getEntryCount() + " entries.”);

}

}

connection.close();

System.out.println(“done.”);

} catch (Exception e) {

e.printStackTrace();

}

}

}

public static void addBuddies() {

for (int i = 0; i < USER_NAMES.length; i++) {

String username = USER_NAMES+;

try {

System.out.println("Adding buddies for " + username + ": ");

XMPPConnection connection = new XMPPConnection(HOST);

connection.login(username, PASSWORD);

Roster roster = connection.getRoster();

for (int k = 0; k < USER_NAMES.length; k++) {

String buddyName = USER_NAMES[k];

// don’'t add the user as its own buddy…

if (buddyName.equals(username))

continue;

System.out.println("\tAdding buddy " + buddyName + " to user " + username + “.”);

roster.createEntry(buddyName + “@” + HOST, buddyName, GROUPS_NAMES);

}

connection.close();

System.out.println(“Adding buddies for " + username + " done.”);

} catch (Exception e) {

e.printStackTrace();

}

}

}

public static void createUsers() throws XMPPException {

XMPPConnection connection = new XMPPConnection(HOST);

AccountManager accountManager = connection.getAccountManager();

for (int i = 0; i < USER_NAMES.length; i++) {

String username = USER_NAMES+;

System.out.print("Creating " + username + ": ");

try {

accountManager.createAccount(username, PASSWORD);

System.out.println(“done.”);

} catch (Exception e) {

System.out.println(“User " + username + " did already exist. Skipping creation.”);

}

}

connection.close();

}

}

Is that enough information? I am happy to provide more, but this is not the right place, is it?!

Btw. Is there any public cvs or svn repository?

How can I format Java code when posting? I haven’'t found that in the online help.

Cheers,

Mariano

We don’‘t allow creating of JIRA accounts, so the forums are the best place to report bugs. I’'ll look into your bug and and let you know what I find.

Thanks,

Matt

Hi Matt,

I just talked to a co-worker and I’'d like to outline to you in which scenario we believe this might happen.

The writing thread W, channeling the packets to be sent, is in its wait block, not holding the monitor right now.

synchronized(queue) {

while (!done && queue.size() == 0) {

try {

queue.wait(2000);

}

catch (InterruptedException ie) { }

}

if (queue.size() > 0) {

return (Packet)queue.removeLast();

}

else {

return null;

}

}

Two Threads (S1 and S2) are sending a single packet each almost simultanously.

synchronized(queue) {

queue.addFirst(packet);

queue.notify();

}

S1 aquires the monitor successfully, S2 also tries that, but doesn’'t succeed and waits for the monitor be available again. S1 enqueues a packet and notify() is called. S1 gives up the monitor and S2 is selected to get the monitor. S2 now enqueues its packet.

Unfortunately it is not guaranteed that W will be notified at all. At some point in time, at latest after 2000ms, W will wakeup and work the queue, but not before that. If close() is called on a connection this will close the connection, before all enqueued packets are sent out.

Changing notify() to notifyAll() will yield in W be woken up too and that it will get the monitor right after S2 gives it up.

Furthermore it would possibly make sense to let shutdown() set done to true and still wait until the queue size is down to 0. Haven’'t tried that though.

Of course, this scenario is more likely to surface with automated tests as with human interactions, but nonetheless it can happen to human beings too.

Cheers,

Mariano

Hi,

am I the only one experiencing the JiveMessenger to crash? The below mentioned example does that to me all the time.

Am I doing something wrong here?

??

Cheers,

Mariano

I’'m a bit confused. What makes Messenger crash?

Regards,

Matt

Hi Matt,

running the code mentioned above doesn’'t work. I always get a IllegalStateException (Not connected to server) error messages, originating in XMPPConnection.sendPacket().

After running it I haven’‘t been able to connect to the Jive Messenger anymore. (Un)fortunately it does work now (the reconnect, not the client) Hmmh… I’'ll try to remember what I changed since last Saturday. Maybe I had another problem then too. I will re-check the notify/notifyAll problem too.

Funny enough, when adding a sleep of 3000ms after the connection.close() in the addBuddies() Method the client works fine.

The code sample works against jabberd 1.4 on debian.

Did you have the chance to run the code?

Cheers,

Mariano