How to get DN and password with UnboundID - java

I need some help concerning UnboundID. I heard it was a great choice but I'm not really used to it.
So I need to make a LDAP listener. On this listener, i should be able to catch bind request (from a ldap browser for example). I wonder how to get the DN and the password. Here is my code for the LDAP listener:
public ResultCode CreateLdapServer () throws LDAPException {
CannedResponseRequestHandler requestHandler = new CannedResponseRequestHandler();
LDAPListenerConfig config =
new LDAPListenerConfig(4243, requestHandler);
try
{
config.setListenAddress(
InetAddress.getByName("localhost"));
}
catch (final Exception e)
{
System.err.println("Unable to create the listen server.");
return ResultCode.PARAM_ERROR;
}
listener = new LDAPListener(config);
try
{
listener.startListening();
System.out.println("Serveur is listening ...");
}
catch (final Exception e)
{
System.err.println("Unable to start listening.");
return ResultCode.LOCAL_ERROR;
}
return ResultCode.SUCCESS;
}
public static void main(String[] args) throws LDAPException {
MyConnection connect = new MyConnection();
connect.CreateLdapServer();
}
I read a lot of UnboundID documentation, but i can't find any simple example of what I need.
Also, i'm not really sure of the utility of CannedResponseRequestHandler. For what i need, is it enough ?
An other question: I'm not sure, but I have the feeling that my server is not listening OR i don't catch anything (when I connect with a ldap Browser, nothing happened). Any Idea / Suggestion ?
Thanks and have a nice day !
EDIT : Thanks to xhochy, I was able to catch the password and the username. As he said, I subclassed LDAPListenerRequestyHandler to override, first, newInstance then ProcessBindRequest. Here is the code (it's absolutely not perfect and it's still a beginning).
public class MyConnection {
private LDAPListener listener;
public MyConnection(){
}
public ResultCode CreateLdapServer() throws LDAPException {
MyLDAPListenerRequestHandler requestHandler = new MyLDAPListenerRequestHandler();
LDAPListenerConfig config =
new LDAPListenerConfig(4243, requestHandler);
try
{
config.setListenAddress(
InetAddress.getByName("localhost"));
}
catch (final Exception e)
{
System.err.println("Unable to create the listen server.");
return ResultCode.PARAM_ERROR;
}
listener = new LDAPListener(config);
try
{
listener.startListening();
System.out.println("Serveur is listening ...");
}
catch (IOException e)
{
System.err.println("Unable to start listening.");
return ResultCode.LOCAL_ERROR;
}
return ResultCode.SUCCESS;
}
public static void main(String[] args) throws LDAPException {
MyConnection connect = new MyConnection();
connect.CreateLdapServer();
}
}
Then the subclass of LDAPListenerRequestHandler:
public class MyLDAPListenerRequestHandler extends LDAPListenerRequestHandler {
#Override
public LDAPListenerRequestHandler newInstance(
LDAPListenerClientConnection arg0) throws LDAPException {
System.out.println("New Instance.");
LDAPConnectionOptions option = new LDAPConnectionOptions();
LDAPConnection connection = new LDAPConnection(option, "yourIPadress", yourport);
System.out.println("Connected to : " + connection.getConnectedAddress()+ " " + connection.getConnectedPort());
return this;
}
#Override
public LDAPMessage processBindRequest(int arg0, BindRequestProtocolOp arg1,
List<Control> arg2) {
System.out.println(arg1.getBindDN());
System.out.println(arg1.getSimplePassword());
return null;
}
}
Thanks again !

Many LDAP server implementations will not return a password and many will not return a password you can use. (ie it maybe a hash).
I would be very curious why there could be a reason to return the password.
-jim

You should subclass LDAPListenerRequestHandler and implement processBindRequest. All the information you are looking for is included in BindRequestProtocolOp (second argument of processBindRequest). Add an empty implementation for all other abstract methods.
If request is your BindRequestProtocolOp instance then you get your information via:
String username = request.getBindDN();
ByteString password = request.getSimplePassword();

Related

How to test the connection in QuickFix/J

I wrote an QuickFix program and created a config file.. Now, when I'm running my application, nothing happens.. So I ask me, how I can recognize if the connection (my program is of type initiator) is established or not.
I've added to the methods that I implement from the Application interface
void fromAdmin(Message message, SessionID sessionId)
void fromApp(Message message, SessionID sessionId)
void onCreate(SessionID sessionId)
void onLogon(SessionID sessionId)
void onLogout(SessionID sessionId)
void toAdmin(Message message, SessionID sessionId)
void toApp(Message message, SessionID sessionId)
a System.out and a logger.info, but nothing of them fires something.
If a connection established, the methods onCreate and onLogon are invoked, or?! So the System.outs in these methods should write something..
But are there any other opportunitys to check wheter the connection established, respectively the config file is valid.
P.S.: I use the SessionSettings to read the config File in.. But I can't find a method in the SessionSettings like validateConfigFile() or something like that.
Has your config file got FileLogPath=log?
Then to debug you look at the FIX messages log, usually in the bin/debug/log directory, which is where it would be for the above config file. If it's not a security risk then paste your config file here please. Also, yes add the System.Out to your Application interface. Here's mine:
public void FromApp(Message msg, SessionID s)
{
Console.WriteLine("IN: " + msg.ToString());
You can download Banzai application which is an accpetor/iniciator with grafic interface. You can iniciate a session, and send/receive messages from your app.
Main class you need in your Iniciator
public class Banzai {
private static final CountDownLatch shutdownLatch = new CountDownLatch(1);
/** enable logging for this class */
private static Logger log = LoggerFactory.getLogger(Banzai.class);
private static Banzai banzai;
private boolean initiatorStarted = false;
private Initiator initiator = null;
private JFrame frame = null;
public Banzai(String[] args) throws Exception {
InputStream inputStream = null;
if (args.length == 0) {
inputStream = new BufferedInputStream(new FileInputStream(new File("config/banzai.cfg")));
} else if (args.length == 1) {
inputStream = new FileInputStream(args[0]);
}
if (inputStream == null) {
System.out.println("usage: " + Banzai.class.getName() + " [configFile].");
return;
}
SessionSettings settings = new SessionSettings(inputStream);
inputStream.close();
boolean logHeartbeats = Boolean.valueOf(System.getProperty("logHeartbeats", "true")).booleanValue();
OrderTableModel orderTableModel = new OrderTableModel();
ExecutionTableModel executionTableModel = new ExecutionTableModel();
BanzaiApplication application = new BanzaiApplication(orderTableModel, executionTableModel);
MessageStoreFactory messageStoreFactory = new FileStoreFactory(settings);
LogFactory logFactory = new ScreenLogFactory(true, true, true, logHeartbeats);
MessageFactory messageFactory = new DefaultMessageFactory();
initiator = new SocketInitiator(application, messageStoreFactory, settings, logFactory, messageFactory);
frame = new BanzaiFrame(orderTableModel, executionTableModel, application);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public synchronized void logon() {
if (!initiatorStarted) {
try {
initiator.start();
initiatorStarted = true;
} catch (Exception e) {
log.error("Logon failed", e);
}
} else {
Iterator<SessionID> sessionIds = initiator.getSessions().iterator();
while (sessionIds.hasNext()) {
SessionID sessionId = (SessionID) sessionIds.next();
Session.lookupSession(sessionId).logon();
}
}
}
public void logout() {
Iterator<SessionID> sessionIds = initiator.getSessions().iterator();
while (sessionIds.hasNext()) {
SessionID sessionId = (SessionID) sessionIds.next();
Session.lookupSession(sessionId).logout("user requested");
}
}
public void stop() {
shutdownLatch.countDown();
}
public JFrame getFrame() {
return frame;
}
public static Banzai get() {
return banzai;
}
public static void main(String args[]) throws Exception {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
log.info(e.getMessage(), e);
}
banzai = new Banzai(args);
if (!System.getProperties().containsKey("openfix")) {
banzai.logon();
}
shutdownLatch.await();
}
}
NOTE: The information in your .settings has to match with the information you have in your code.
After you start both codes you will start to receive logon, and heartbeat messages.

How to remotely connect to multiple Glassfish 4+ instances simultaneously?

I am looking for a way to connect to multiple instances of Glassfish 4+ (JDK7-EE) simultaneously from a stand-alone Swing-based client (JDK7-SE). I successfully connect to a single instance by the following way:
That's the construction of the initial context:
private void connect(String address, String port) {
System.setProperty("java.naming.factory.initial", "com.sun.enterprise.naming.SerialInitContextFactory");
System.setProperty("com.sun.corba.ee.transport.ORBTCPTimeouts", "500:30000:20:"+Integer.MAX_VALUE);
System.setProperty("com.sun.corba.ee.transport.ORBTCPConnectTimeouts", "250:90000:100:"+Integer.MAX_VALUE);
System.setProperty("com.sun.corba.ee.transport.ORBWaitForResponseTimeout", "300000");
System.setProperty("java.security.auth.login.config", new File("login.conf").getAbsolutePath());
System.setProperty("org.omg.CORBA.ORBInitialHost", address);
System.setProperty("org.omg.CORBA.ORBInitialPort", port);
InitialContext context = new InitialContext();
}
Look-ups are done by JNDI using a remote interface:
context.lookup("java:global/LawSuiteEE/LawSuiteEE-ejb/GlobalsFacade!ch.lawsuite.control.GlobalsFacadeRemote");
I am using a custom JDBC realm that resides on the server and works fine. On the client side I pass the following login.conf to the initial context (see code above):
default {
com.sun.enterprise.security.auth.login.ClientPasswordLoginModule required debug=true;
};
Authentication is currently done by ProgrammaticLogin:
private void login(String username, char[] password) {
ProgrammaticLogin plogin = new ProgrammaticLogin();
plogin.login(username, password);
}
All of this is working fine! But during startup of the stand-alone client, I want to simultaneously connect to another EJB located on a different server.
Since ProgrammaticLogin has no direct relation to the initial context, I am not sure how to login to two different Glassfish servers simulteneously with different credentials (e.g. username/password) ? Someone any ideas ?
Further examination of the issue has uncovered, that the initial context can only be set once on a per JVM basis. So as soon as the ORB is set up by using System.setProperty(String, String) and the inital context object is instantiated, the design of the SerialInitContextFactory let's you no more change the selected endpoint(s).
Therefore I decide to connect within different JVMs to the different Glassfish servers. So finally I ended up with a separate project that manages the connections to the application server and communicates by RMI with the main project.
Currently my project consists of two different EE projects to which I want connect simultaneously, namely "LawSuiteEE" and "MgmtCenterEE". Here's the new project that handles the connections:
public static void main(String args[]) {
try {
if(args.length==2) {
if(args[1].equals("LawSuiteEE")) {
ILawSuiteEE stub = (ILawSuiteEE) UnicastRemoteObject.exportObject(new LawSuiteEE(), 0);
Registry registry = LocateRegistry.createRegistry(Integer.parseInt(args[0]));
registry.bind("LawSuiteEE", stub);
} else if(args[1].equals("MgmtCenterEE")) {
ILawSuiteEE stub = (ILawSuiteEE) UnicastRemoteObject.exportObject(new MgmtCenterEE(), 0);
Registry registry = LocateRegistry.createRegistry(Integer.parseInt(args[0]));
registry.bind("MgmtCenterEE", stub);
} else {
throw new NumberFormatException();
}
Logger.getLogger(RemoteContext.class.getName()).log(Level.INFO, "Remote context service is listening on port "+args[0]+" for incoming requests delegating to "+args[1]+".");
System.out.println("SIGNAL[READY]");
} else {
throw new NumberFormatException();
}
} catch (RemoteException ex) {
System.exit(1);
} catch (AlreadyBoundException ex) {
System.exit(2);
} catch(NumberFormatException ex) {
System.exit(3);
}
The interface ILawSuiteEE is used for RMI between this and the main project (the second interface IMgmtCenterEE is quite the same):
public interface ILawSuiteEE extends IConcurrentDatastore {
void connect(String address, String port) throws RemoteException;
void disconnect() throws RemoteException;
boolean login(String username, char[] password) throws RemoteException;
}
The appropriate implementation:
public class LawSuiteEE implements ILawSuiteEE {
private InitialContext context;
private ProgrammaticLogin login;
#Override
public void connect(String address, String port) throws RemoteException {
if(context==null) {
try {
System.setProperty("java.naming.factory.initial", "com.sun.enterprise.naming.SerialInitContextFactory");
System.setProperty("com.sun.corba.ee.transport.ORBTCPTimeouts", "500:30000:20:"+Integer.MAX_VALUE);
System.setProperty("com.sun.corba.ee.transport.ORBTCPConnectTimeouts", "250:90000:100:"+Integer.MAX_VALUE);
System.setProperty("com.sun.corba.ee.transport.ORBWaitForResponseTimeout", "300000");
System.setProperty("java.security.auth.login.config", new File("login.conf").getAbsolutePath());
System.setProperty("org.omg.CORBA.ORBInitialHost", address);
System.setProperty("org.omg.CORBA.ORBInitialPort", Integer.toString(port));
Logger.getLogger(RemoteDatastore.class.getName()).log(Level.INFO, "Try to connect to application server at "+System.getProperty("org.omg.CORBA.ORBInitialHost")+":"+System.getProperty("org.omg.CORBA.ORBInitialPort")+" ...");
context = new InitialContext();
} catch (NamingException ex) {
throw new RemoteException(ex.getMessage());
}
}
}
#Override
public void disconnect() throws RemoteException {
if(context!=null) {
try {
context.close();
Logger.getLogger(LawSuiteEE.class.getName()).log(Level.INFO, "Server context successfully closed.");
} catch (NamingException ex) {
Logger.getLogger(LawSuiteEE.class.getName()).log(Level.SEVERE, "Couldn't close server context.");
} finally {
this.facades.clear();
this.services.clear();
this.context=null;
}
}
}
#Override
public boolean login(String username, char[] password) throws RemoteException {
login = new ProgrammaticLogin();
return login.login(username, password);
}
}
In the main project I'm going to connect with the following:
public class LawSuiteDatastore extends Thread implements ILawSuiteEE {
private int port;
private int trials;
private boolean ready;
private Process process;
private ILawSuiteEE stub;
public LawSuiteDatastore() {
this.setName("K+: Remote-Datastore-Connection");
this.port = RemoteDatastoreService.cport++;
}
#Override
public void run() {
try {
Tools.log(RemoteDatastoreService.class, Level.INFO, "Starting RMI registry on port "+port+" for connecting to LawSuiteEE server instance.");
this.process = Runtime.getRuntime().exec(new String[] {"java", "-jar", Context.getWorkingDirectory()+"/lib/LawSuiteSX.jar", Integer.toString(port), "LawSuiteEE"});
//<editor-fold defaultstate="collapsed" desc="Redirect Error Stream">
new Thread(new Runnable() {
#Override
public void run() {
try{
try(DataInputStream in = new DataInputStream(process.getErrorStream())) {
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line;
while((line=br.readLine())!=null) {
Tools.log(RemoteDatastoreService.class, Level.SEVERE, line);
}
}
} catch(Exception ex){
Tools.log(MgmtCenterDatastore.class, Level.SEVERE, ex.getMessage());
}
}
}).start();
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Redirect Output Stream">
new Thread(new Runnable() {
#Override
public void run() {
try{
try(DataInputStream in = new DataInputStream(process.getInputStream())) {
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line;
while((line=br.readLine())!=null) {
if(line.contains("SIGNAL[READY]")) { ready=true; }
Tools.log(RemoteDatastoreService.class, Level.INFO, line);
}
}
} catch(Exception ex){
Tools.log(MgmtCenterDatastore.class, Level.SEVERE, ex.getMessage());
}
}
}).start();
//</editor-fold>
// keep thread alive as long process is alive
if(process.waitFor()>0) {
// port was already bound
if(process.exitValue()==2) {
// try it with a different port and start over again
if(trials<3) {
process = null;
port = ++RemoteDatastoreService.cport;
trials++;
if(trials<3) {
start();
}
}
}
}
} catch (IOException ex) {
Tools.log(RemoteDatastoreService.class, Level.SEVERE, ex.getMessage());
} catch (InterruptedException ex) {
Tools.log(RemoteDatastoreService.class, Level.SEVERE, ex.getMessage());
}
}
public boolean isReady() {
return ready;
}
public int getTrials() {
return trials;
}
#Override
public void connect(RemoteDatastore datastore) throws RemoteException {
try {
Tools.log(RemoteDatastoreService.class, Level.INFO, "Locating RMI registry on port "+port+" for connecting to LawSuiteEE server instance.");
Registry registry = LocateRegistry.getRegistry(port);
stub = (ILawSuiteEE)registry.lookup("LawSuiteEE");
stub.connect(datastore);
} catch (NotBoundException ex) {
Logger.getLogger(RemoteDatastoreService.class.getName()).log(Level.SEVERE, null, ex);
}
}
#Override
public void disconnect() throws RemoteException {
if(process!=null && stub!=null) {
stub.disconnect();
process.destroy();
} else {
throw new RemoteException("Remote RMI server is not ready.");
}
}
#Override
public boolean login(String username, char[] password) throws RemoteException {
if(process!=null && stub!=null) {
return stub.login(username, password);
} else {
throw new RemoteException("Remote RMI server is not ready.");
}
}
}
How about using multiple threads, one for each server?
You can create a new thread for each connection you need, set up the InitialContext on each thread and connect with the ProgrammaticLogin with different credentials.
You can create your own "custom" thread by implementing the Runnable interface, and create a constructor for it that receives the credentials and/or InitialContext object.
Simple example:
public class MyThread implements Runnable {
private ProgrammaticLogin plogin;
private string user;
private char[] pass;
public MyThread(String username, char[] password,InitialContext context) {
this.user = username;
this.pass = password;
this.plogin = new ProgrammaticLogin();
//add more code here if needed
}
public void run() {
//insert code here when thread will run
}
}
and invoke it thus:
Runnable thread1 = new MyThread("my user1","my pass1",ContextObject1);
Runnable thread2 = new MyThread("my user2","my pass2",ContextObject2);
new Thread(thread1).start();
new Thread(thread2).start();
Of course this is a very simple example and it might not be suitable for your exact needs, but i think it is a good start for what you need. Since each Context and login credentials will run on a different thread they will have their own separate execution stack and you should not experience any concurrency issues (two threads accessing the same object).
However, you should have a good understanding of concurrency and threads otherwise you might run into different exceptions, that are a bit harder to debug due to using multiple threads.
Tom.

Kryonet not receiving custom classes

I'm trying to set up a basic client and server to get the hang of networking, but I'm running into a problem.
Whenever I send a class with one of my own classes as a variable, the server does not receive it. I can use a string/int/etc for the variable perfectly fine but whenever a variable of my own type is included it is not received, along with all objects I try to send after it.
Everything is registered with Kryo. Am I just missing something? Any help is appreciated!
From GameClient:
public GameClient(String name) {
client = new Client();
client.start();
NetworkManager.register(client);
listener = new ClientListener();
client.addListener(listener);
try {
client.connect(5000, "24.207.67.56", NetworkManager.port);
} catch (Exception e) {
e.printStackTrace();
}
Login login2 = new Login();
User user2 = new User(name);
login2.user = user2;
login2.name = user2.name;
client.sendTCP(login2); // server does not recieve this
Login login = new Login();
login.name = user.name;
client.sendTCP(login); // server receives this only when it is sent before the Login containing the User
}
From GameServer :
public GameServer() {
server = new Server();
NetworkManager.register(server);
listener = new ServerListener(server);
server.addListener(listener);
try {
server.bind(NetworkManager.port);
} catch (IOException e) {
e.printStackTrace();
}
server.start();
}
In ServerListener:
#Override
public void received(Connection c, Object o) {
System.out.println("recieved");
if (o instanceof Login) {
System.out.println("[SERVER] " + ((Login) o).name + " logged in.");
LoginResult lr = new LoginResult();
lr.result = true;
c.sendTCP(lr);
}
}
From NetworkManager:
public static void register(EndPoint endPoint) {
Kryo kryo = endPoint.getKryo();
kryo.register(Login.class);
kryo.register(User.class);
}
public static class Login {
public User user;
public String name;
}
User:
public class User {
public String name;
public User(String name) {
this.name = name;
}
}
So it turns out that the problem was caused by the lack of default constructor in the User class. Removing the User(String name) constructor or adding a plain User() constructor fixes the issue.
It would be useful if it threw an error when you tried to do it incorrectly, but oh well.

Java RMI with Callable

I have a server and several clients. The server should be able to delegate tasks to the clients so I tried to implement RMI. I followed this tutorial and everything is working fine if I use String as param- and/or return-value.
Now the server should send undefined tasks to the clients so I tried to use a Callable as param but the program crashed with a NotSerializableException. Since Callable doesn't implement the Serializeable interface thats the result I expected.
Now I found several sources that use Callable and Runnable as params and that confuses me. Is there any trick to get it to work? Or do i miss something important? Maybe theres a technology that fits better?
Resource1 S. 33
Resource2 s. 5
And heres my code:
// Client
public static void main(String[] args) throws InterruptedException {
App app = new App();
app.startClient();
Thread.sleep(20000);//just for test purpose
}
private void startClient() {
try {
// create on port 1099
Registry registry = LocateRegistry.createRegistry(1099);
// create a new service named myMessage
registry.rebind("calcClient", new CalculateRemoteImpl<String>());
} catch (RemoteException e) {
e.printStackTrace();
}
System.out.println("System is ready");
}
// RemoteInterface
public interface CalculateRemote<T> extends Remote {
public T hello(Callable<T> hello) throws RemoteException;
}
// RemoteInterfaceImpl
public class CalculateRemoteImpl<T> extends UnicastRemoteObject implements CalculateRemote<T> {
public T hello(Callable<T> hello) throws RemoteException {
return (T) ("Hello " + hello);// just print address of object
}
}
.
// Server
public static void main(String[] args) {
App app = new App();
app.doTest();
}
private void doTest() {
try {
// fire to localhost port 1099
Registry myRegistry = LocateRegistry.getRegistry("127.0.0.1", 1099);
// search for myMessage service
CalculateRemote<String> impl = (CalculateRemote<String>) myRegistry.lookup("calcClient");
// call server's method
System.out.println("Message: " + impl.hello(new Callable<String>() {
public String call() throws RemoteException, Exception {
return "hello";
}
}));
System.out.println("Message Sent");
} catch (NotBoundException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
}
}
// And the same RemoteInterface
public interface CalculateRemote<T> extends Remote {
public T hello(Callable<T> hello) throws RemoteException;
}
.
// stacktrace
java.rmi.MarshalException: error marshalling arguments; nested exception is:
java.io.NotSerializableException: de.fhb.rmicalcserver.App$1
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:156)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:194)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:148)
at $Proxy0.hello(Unknown Source)
at de.fhb.rmicalcserver.App.doTest(App.java:30)
at de.fhb.rmicalcserver.App.main(App.java:18)
Caused by: java.io.NotSerializableException: de.fhb.rmicalcserver.App$1
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1180)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
at sun.rmi.server.UnicastRef.marshalValue(UnicastRef.java:292)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:151)
If you want to send objects to clients whose classes aren't deployed at the client you need to take a long look at the RMI codebase feature.

Smack Presence Doesn't Work

Actually I programming a IM service (inherited google chat) by using smack API. But when i want to print buddy list and their presences, the compile mode show all presences unavailable, but in the debug mode it shows the real availability!
My code is ...
1- create connection
public boolean openConnection() {
ConnectionConfiguration connectionConfiguration = new ConnectionConfiguration("talk.google.com", 5222, "mail.google.com");
this.connection = new XMPPConnection(connectionConfiguration);
try {
this.connection.connect();
} catch (XMPPException e) {
// TODO: Send Error Information To Programmer's Email Address
}
if(this.connection.isConnected()) {
this.roster = this.connection.getRoster();
this.roster.addRosterListener(new RosterListener() {
public void entriesAdded(Collection<String> addresses) {}
public void entriesDeleted(Collection<String> addresses) {}
public void entriesUpdated(Collection<String> addresses) {}
public void presenceChanged(Presence presence) {}
});
return true;
}
return false;
}
2- login
public boolean login(String jid, String password) {
try {
this.connection.login(jid, password, "smack");
} catch (XMPPException e) {
// TODO: Send Error Information To Programmer's Email Address
}
if(this.connection.isAuthenticated()) return true;
return false;
}
3- buddy list
public void buddiesList() {
Collection<RosterEntry> rosterEntries = this.roster.getEntries();
for(RosterEntry rosterEntry: rosterEntries) {
System.out.println(rosterEntry.username() + " === " + this.roster.getPresence(rosterEntry.getUser()));
}
}
4- implementation
public static void main(String args[]) {
IMService imService = new IMService();
imService.openConnection();
imService.login("google account", "password");
imService.buddiesList();
}
Your RosterListener doesn't do anything. This is where you have to put code to update your roster when things like presence messages are received.
The presence you are retrieving is a snapshot in time of what the state was when it was created. To keep the state current, you have to actually code the RosterListener. This is clearly stated in the Javadoc for the getPresence() method.
Adding a Listener to your roster could be better:
https://www.igniterealtime.org/builds/smack/docs/latest/documentation/extensions/rosterexchange.html

Categories