src/main/java/org/jivesoftware/smack/UserRoster.java
public void createEntry(String user, String name, String[] groups)
            throws XMPPException {
        if (!connection.isAuthenticated()) {
            throw new IllegalStateException("Not logged in to server.");
        }
        if (connection.isAnonymous()) {
            throw new IllegalStateException(
                    "Anonymous users can't have a roster.");
        }

        // Create and send roster entry creation packet.
        Roster rosterPacket = new Roster();
        rosterPacket.setType(IQ.Type.set);
        rosterPacket.addItem(new JID(user), name, null, null,
                Arrays.asList(groups));
        // Wait up to a certain number of seconds for a reply from the server.
        PacketCollector collector = connection
                .createPacketCollector(new PacketIDFilter(rosterPacket.getID()));
        connection.sendPacket(rosterPacket);
        IQ response = (IQ) collector.nextResult(SmackConfiguration
                .getPacketReplyTimeout());
        collector.cancel();
        if (response == null) {
            throw new XMPPException("No response from the server.");
        }
        // If the server replied with an error, throw an exception.
        else if (response.getType() == IQ.Type.error) {
            throw new XMPPException(response.getError());
        }

        // Create a presence subscription packet and send.
        Presence presencePacket = new Presence(Presence.Type.subscribe);
        presencePacket.setTo(user);
        connection.sendPacket(presencePacket);
    }
public void createEntry(String user, String name, String[] groups)
            throws XMPPException {
        if (!connection.isAuthenticated()) {
            throw new IllegalStateException("Not logged in to server.");
        }
        if (connection.isAnonymous()) {
            throw new IllegalStateException(
                    "Anonymous users can't have a roster.");
        }

        // Create and send roster entry creation packet.
        Roster rosterPacket = new Roster();
        rosterPacket.setType(IQ.Type.set);
        rosterPacket.addItem(new JID(user), name, null, null,
                Arrays.asList(groups));
        // Wait up to a certain number of seconds for a reply from the server.
        PacketCollector collector = connection
                .createPacketCollector(new PacketIDFilter(rosterPacket.getID()));
        connection.sendPacket(rosterPacket);
        IQ response = (IQ) collector.nextResult(SmackConfiguration
                .getPacketReplyTimeout());
        collector.cancel();
        if (response == null) {
            throw new XMPPException("No response from the server.");
        }
        // If the server replied with an error, throw an exception.
        else if (response.getType() == IQ.Type.error) {
            throw new XMPPException(response.getError());
        }

        // Create a presence subscription packet and send.
        Presence presencePacket = new Presence(Presence.Type.subscribe);
        presencePacket.setTo(user);
        connection.sendPacket(presencePacket);
    }
Creates a new roster entry and presence subscription. The server will
asynchronously update the roster with the subscription status.

@param user
the user. (e.g. johndoe@jabber.org)
@param name
the nickname of the user.
@param groups
the list of group names the entry will belong to, or
<tt>null</tt> if the the roster entry won't belong to a group.
@throws XMPPException
if an XMPP exception occurs.
@throws IllegalStateException
if connection is not logged in or logged in anonymously