ICEPush is not pushing when it's called via JMS Message

Hi, in my application, after login, a JMS Message is received and I replace my LoginWindow by a MainWindow.

That works as expected, but I’m trying to use ICEPush because I’m only able to see the MainWindow after I hit F5.

However, it seems ICEPush is not working. Maybe it’s my fault. That’s how I did it (LoginControllerImpl class snippet):

public LoginControllerImpl(ProcessApplication application, UserModel userModel) {
   this.application = application;
   this.userModel = userModel;
   view = new LoginWindow(this);
   view.addComponent(application.getPusher());

   try {
      consumer = application.createConsumer("process.login.success");
      consumer.setMessageListener(new MessageListener() {

         public void onMessage(Message message) { // called when JMS message arrives
            ObjectMessage objectMessage = (ObjectMessage) message;
            try {
               UserEvent event = (UserEvent) objectMessage.getObject();
               loginSuccess(event);
            } catch (Throwable e) {
               e.printStackTrace();
            }
         }

      });
   } catch (JMSException e) {
      throw new RuntimeException(e.getMessage(), e);
   }
}

public void loginSuccess(UserEvent payload) {
   synchronized (application) {
      MainController controller = new MainControllerImpl(userModel);
      controller.getView().addComponent(application.getPusher());
      application.changeMainWindow(controller.getView());
   }

   application.push();
}

public void login(String username, String password) {
   userModel.login(username, password); // login() sends the JMS message
}

A snippet of my application class:

public void changeMainWindow(Window newWindow) {
   removeWindow(getMainWindow());
   setMainWindow(newWindow);
}

public ICEPush getPusher() {
   return pusher;
}

public void push() {
   pusher.push();
}

I can see some ICEPush related entries in Firebug, like:

  • GET code.icepush
  • POST create-push-id.icepush
  • POST listen.icepush

I’m using Vaadin 6.6.5 and ICEPush 0.2.1.

Could you, guys, please help me here? Do you need any more information?

Looked at your code quickly. The pusher must be attached to your main window, and I’m not sure your code ensures this. In my Application class, I ended up defining the following methods to make sure the pusher was always on the main window no matter what I did.

 
    synchronized protected ICEPush ensurePusher() {
        if (pusher == null) {
            pusher = new ICEPush();
            getMainWindow().addComponent(pusher);
        }
        return pusher;
    }

    synchronized public void push() {
        pusher = this.ensurePusher();
        if (!pusherDisabled) {
                logger.debug("pushing with {} on window {}",pusher,getMainWindow());
                pusher.push();
        }
    }

Thank you for yout tip, I’ll use your technique in my project, but, unfortunately, that’s not the problem. The pusher is attached to the application, the methods are called as expected and no exception is thrown.

I have written a small class that demonstrates ICEPush is configured properly but it is not working when push() is called inside a JMS MessageListener.

There are two buttons: the first is working and doesn’t use JMS. The second is NOT working and uses a JMS MessageListener. Why is it not working?

This way ICEPush works:

public void buttonClick(ClickEvent event) {
   Window w = new Window();
   w.addComponent(pusher);
   w.addComponent(new Label("Waiting for background process to complete..."));
   setMainWindow(w);
   new BackgroundThread().start();
}

class BackgroundThread extends Thread {
   public void run() {
      try {
         Thread.sleep(5000);
      } catch (InterruptedException e) {
         System.out.println("end of sleep");
      }

      synchronized (TesteApplication.this) {
         getMainWindow().addComponent(new Label("All done"));
      }

      pusher.push(); // now I can see the 'All done' label
   }
}

This other way ICEPush does not work, and my question is: why?

public void buttonClick(ClickEvent event) {
   TextMessage message;
   try {
      message = session.createTextMessage();
      message.setText("This is the message");

      MessageProducer producer = session.createProducer(lookupDestination("process.login.success"));
      System.out.println("Sending the message");
      producer.send(message);
      System.out.println("Message sent"); // the message is sent, no exception is thrown
   } catch (JMSException e) {
      e.printStackTrace();
   }
}

// this is called asynchronously by the JMS
public void onMessage(Message message) {
   System.out.println("Message received");
   TextMessage textMessage = (TextMessage) message;

   Window w = new Window();
   try {
      w.addComponent(new Label(textMessage.getText()));
   } catch (JMSException e) {
      e.printStackTrace();
   }

   synchronized (this) {
      setMainWindow(w);
      w.addComponent(pusher);
   }

   // here the new window showing the message text is not displayed.
   // I can see the new window only if I hit F5.
   pusher.push();
   System.out.println("Changes were pushed");
}

Please, take a look at the attached class or contact me if you need more information.

Thanks for your help,
11880.java (3.88 KB)

Do you understand my problem? I haven’t found a solution yet…

Thanks,

My problem has nothing to do with JMS, but with setMainWindow…

ICEPush works properly when the background thread changes only the content of the main window. But when setting a new main window I have to do it this way:
http://vaadin.com/forum/-/message_boards/view_message/83885#_19_message_100711