The example I gave really does work, I promise. The null was simply because the XMPPConnection does something I don’‘t think it should, it only stores the username for successful logins. I think it’‘s a bug in Smack but it’'s one of those kind of things that the Smack developers might call a feature.
After using Smack for a little while I’‘ve found the Chat class to be kind of worthless so I’‘ve modified the example to avoid using it. I’‘ve also created a junk gtalk account so I could leave the username and password values in the example. If you had a problem with the last example it’'s probably because you were using username@gmail.com instead of just username. Run this example with
java SendTest
to just wait for messages and auto-reply to them. Run with
to do the same but also send a single message to start the conversation.
This example runs with zero modifications but remember if you don’'t change the username and password values then everyone running the example is going to be logged in at the same time and I think only one of you is going to get the messages.
import java.io.IOException;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.filter.MessageTypeFilter;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.util.StringUtils; public class SendTest {
// Notice the username is NOT smack.test@gmail.com
private static String username = "smack.test";
private static String password = "ignite";
public static class MessageParrot implements PacketListener {
private XMPPConnection xmppConnection;
public MessageParrot(XMPPConnection conn) {
xmppConnection = conn;
}
public void processPacket(Packet packet) {
Message message = (Message)packet;
if(message.getBody() != null) {
String fromName = StringUtils.parseBareAddress(message.getFrom());
System.out.println("Message from " + fromName + "\n" + message.getBody() + "\n");
Message reply = new Message();
reply.setTo(fromName);
reply.setBody("I am a Java bot. You said: " + message.getBody());
xmppConnection.sendPacket(reply);
}
}
};
public static void main( String[] args ) {
System.out.println("Starting IM client");
// gtalk requires this or your messages bounce back as errors
ConnectionConfiguration connConfig = new ConnectionConfiguration("talk.google.com", 5222, "gmail.com");
XMPPConnection connection = new XMPPConnection(connConfig);
try {
connection.connect();
System.out.println("Connected to " + connection.getHost());
} catch (XMPPException ex) {
//ex.printStackTrace();
System.out.println("Failed to connect to " + connection.getHost());
System.exit(1);
}
try {
connection.login(username, password);
System.out.println("Logged in as " + connection.getUser());
Presence presence = new Presence(Presence.Type.available);
connection.sendPacket(presence);
} catch (XMPPException ex) {
//ex.printStackTrace();
// XMPPConnection only remember the username if login is succesful
// so we can''t use connection.getUser() unless we log in correctly
System.out.println("Failed to log in as " + username);
System.exit(1);
}
PacketFilter filter = new MessageTypeFilter(Message.Type.chat);
connection.addPacketListener(new MessageParrot(connection), filter);
if(args.length > 0) {
// google bounces back the default message types, you must use chat
Message msg = new Message(args[0], Message.Type.chat);
msg.setBody("Test");
connection.sendPacket(msg);
}
System.out.println("Press enter to disconnect\n");
try {
System.in.read();
} catch (IOException ex) {
//ex.printStackTrace();
}
connection.disconnect();
}
}
I’‘m using Smack 3.0.2, Windows XP, and JDK 1.6 but it might be a location problem. I’'ve only tried at locations within the United States. I think in the UK and in Germany there was an issue with the GMail.com domain what about if you try
ConnectionConfiguration conf = new ConnectionConfiguration("talk.google.com", 5222, "googlemail.com");
I doubt it’‘s your Java as long as it runs and compiles. You tried with the googlemail.com domain and an account created in the UK? I’‘d suggest creating a jabber.org account and modifying the connection info, username, and password just to make sure this is a server issue and nothing with your environment. Once that’‘s working then use a IM client like pidgin to figure out the settings you need in the UK for gtalk. If anyone has a UK computer that I can have remote access to (RDP/VNC) with Java I’‘d be more than happy to work on this problem but there doesn’'t seem to be anything else I can do from my current location.
ConnectionConfiguration connConfig = new ConnectionConfiguration(“jabber.org”, 5222, “jabber.org”);
and use my jabber.org username and password, it connects fine! Shall I email you the ssh details of my host and you can try to see if you can get it working on there?
Just want to confirm that with 3.0.3 it does seem broken. I get this:
SASL authentication failed:
at org.jivesoftware.smack.SASLAuthentication.authenticate(SASLAuthentication.java:209)
at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:341)
at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:301)
at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:283)
at test.SendTest.main(SendTest.java:85)
Thanks for the bug report. I re-opened SMACK-224 and marked it to be fixed for the next release. I’'m going to have to figure out some way to make both SSO and Google work, though.
It was a simple fix. The PLAIN mech was using an authentication ID equal to the username@hostname. In prior versions the hostname was set to the xmpp domain, but to make things work with SSO it needs to be the FQDN of the server, which may not match (indeed, it often wont). But as I said, the solution is simple. The PLAIN mechanism dosnt require an authentication ID, and in fact the way its being used in Smack wouldnt allow you to do anything useful with it anyway. So we just made that field empty.