Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Rich Client Platform (RCP) » EventBroker.post does not reach @UIEventTopic method
EventBroker.post does not reach @UIEventTopic method [message #1716429] Thu, 03 December 2015 16:43 Go to next message
Christopher Roscoe is currently offline Christopher RoscoeFriend
Messages: 1
Registered: December 2015
Junior Member
I have an eclipse rcp 4 application running on Windows 8.1.
One of my use cases is to start a asynchronous service on a remote backend and have a dialog that is listening on JMS messages from the remote backend.
There are several JMS messages indicating different processing steps and the dialog should react on those steps and draw update informations.
At some point the service is done and a last message is send indicating the termination of the process. The dialog can be closed. Then it is possible to trigger the use case again.

Most of the time my solution works flawlessly.
But there is the rare case that my dialog is opened and from the beginning gets no update messages. From what i see in the backend log the service is processed successfully.
But for the user the whole use case seems to be broken.

My solution:

There is a handler, that

1. creates the dialog if not present (i reuse the same object)
2. starts a JMS listener, that post the message to the injected org.eclipse.e4.core.services.events.IEventBroker
3. calls the backend service
4. opens the dialog
5. stops the JMS listener

The dialog has a method annotated with @UIEventTopic.

@Inject
@Optional
public void notifyUpdate(@UIEventTopic(EventConstants.TOPIC) MyUpdate myUpdate) {


There is no observable issue with the messaging.
I found out that even in the broken case the eventBroker.post(EventConstants.TOPIC, message) is processed without exception,
but the event never reaches the dialog methods.

I did some tracing afterwards. The control flow after eventBroker.post goes into EventHandlerTracker.getHandlers to get the listeners for the topic. In the normal case i observe the returned set containing 2 objects. In the broken case the returned set is empty for the same topic.

public synchronized Set<EventHandlerWrapper> org.eclipse.equinox.internal.event.EventHandlerTracker.getHandlers(final String topic)

I use this version org.eclipse.equinox.event_1.3.100.v20140115-1647.jar.

What am i doing wrong?
    package demo;

    import java.util.function.Function;

    import javax.inject.Inject;

    import org.eclipse.e4.core.contexts.ContextInjectionFactory;
    import org.eclipse.e4.core.contexts.IEclipseContext;
    import org.eclipse.e4.core.di.annotations.Execute;
    import org.eclipse.e4.core.services.events.IEventBroker;
    import org.eclipse.jface.window.Window;

    public class Handler {

        private Function<IEclipseContext, MyDialog> dialogFactory =
            context -> ContextInjectionFactory.make(MyDialog.class, context);

        @Inject
        private IEventBroker eventBroker;

        private MyDialog myDialog;

        @Inject
        private MyService myService;

        private MessagingDelegate messagingDelegate;

        @Execute
        public void execute(IEclipseContext context) throws Exception {

            MyContext context = new MyContext();

            if (myDialog == null) {
                myDialog = dialogFactory.apply(context);
            }

            messagingDelegate.start(context.getQueueName(), message -> {
                eventBroker.post(EventConstants.TOPIC, message);
            });

            myService.start(context);

            myDialog.open();

            messagingDelegate.stop();
        }

        @Inject
        public void setMessagingDelegateFactory(MessagingDelegateFactory messagingDelegateFactory) {
            messagingDelegate = messagingDelegateFactory.createMessagingDelegate();
        }
    }

The dialog implementation.
	package demo;

	import java.util.Objects;

	import javax.inject.Inject;

	import org.eclipse.e4.core.di.annotations.Optional;
	import org.eclipse.e4.core.services.nls.Translation;
	import org.eclipse.e4.ui.di.UIEventTopic;
	import org.eclipse.jface.dialogs.Dialog;
	import org.eclipse.jface.dialogs.IDialogConstants;
	import org.eclipse.jface.layout.GridDataFactory;
	import org.eclipse.jface.layout.GridLayoutFactory;
	import org.eclipse.swt.SWT;
	import org.eclipse.swt.events.SelectionAdapter;
	import org.eclipse.swt.events.SelectionEvent;
	import org.eclipse.swt.graphics.Point;
	import org.eclipse.swt.widgets.Button;
	import org.eclipse.swt.widgets.Composite;
	import org.eclipse.swt.widgets.Control;
	import org.eclipse.swt.widgets.Label;
	import org.eclipse.swt.widgets.ProgressBar;
	import org.eclipse.swt.widgets.Shell;

	public class MyDialog extends Dialog {

		@Inject
		@Optional
		public void notifyUpdate(@UIEventTopic(EventConstants.TOPIC) MyUpdate myUpdate) {
			if (myUpdate != null) {
				updateInformation(myUpdate);
			}
		}

		private void updateInformation(MyUpdate myUpdate) {
			label.setText(myUpdate.getInfo());
		}
	}
Re: EventBroker.post does not reach @UIEventTopic method [message #1716564 is a reply to message #1716429] Fri, 04 December 2015 20:27 Go to previous message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
Hi,

My wild guess (i have not looked at the handler code) is that the
context you get there is a temporary one which is only valid while the
@Execute-method is running.

You can check if this is true by adding an @PreDestroy in the MyDialog
if it is called then this means that you @UIEventTopic gets unregistered
as well.

The reason is sometimes work might be caused by GC because we are using
WeakRefs internally and so thing might not get collected immediately.

The only solution is see is that you use a context always available eg
using the one attached to MApplication / MWindow / MPart who are
guaranteed to be there while your dialog is up and running.

so your code should most likely look like this

public void execute(@Named(IServiceConstants.ACTIVE_PART) MPart part)
throws Exception {
IEclipseContext context = part.getContext();
// ...
}

Tom

On 04.12.15 14:56, Christopher Roscoe wrote:
> I have an eclipse rcp 4 application running on Windows 8.1.
> One of my use cases is to start a asynchronous service on a remote
> backend and have a dialog that is listening on JMS messages from the
> remote backend. There are several JMS messages indicating different
> processing steps and the dialog should react on those steps and draw
> update informations.
> At some point the service is done and a last message is send indicating
> the termination of the process. The dialog can be closed. Then it is
> possible to trigger the use case again.
>
> Most of the time my solution works flawlessly.
> But there is the rare case that my dialog is opened and from the
> beginning gets no update messages. From what i see in the backend log
> the service is processed successfully.
> But for the user the whole use case seems to be broken.
>
> My solution:
>
> There is a handler, that
> 1. creates the dialog if not present (i reuse the same object)
> 2. starts a JMS listener, that post the message to the injected
> org.eclipse.e4.core.services.events.IEventBroker
> 3. calls the backend service
> 4. opens the dialog
> 5. stops the JMS listener
>
> The dialog has a method annotated with @UIEventTopic.
>
> @Inject
> @Optional
> public void notifyUpdate(@UIEventTopic(EventConstants.TOPIC) MyUpdate
> myUpdate) {
>
>
> There is no observable issue with the messaging.
> I found out that even in the broken case the
> eventBroker.post(EventConstants.TOPIC, message) is processed without
> exception,
> but the event never reaches the dialog methods.
>
> I did some tracing afterwards. The control flow after eventBroker.post
> goes into EventHandlerTracker.getHandlers to get the listeners for the
> topic. In the normal case i observe the returned set containing 2
> objects. In the broken case the returned set is empty for the same topic.
>
> public synchronized Set<EventHandlerWrapper>
> org.eclipse.equinox.internal.event.EventHandlerTracker.getHandlers(final
> String topic)
>
> I use this version org.eclipse.equinox.event_1.3.100.v20140115-1647.jar.
>
> What am i doing wrong?
>
> package demo;
>
> import java.util.function.Function;
>
> import javax.inject.Inject;
>
> import org.eclipse.e4.core.contexts.ContextInjectionFactory;
> import org.eclipse.e4.core.contexts.IEclipseContext;
> import org.eclipse.e4.core.di.annotations.Execute;
> import org.eclipse.e4.core.services.events.IEventBroker;
> import org.eclipse.jface.window.Window;
>
> public class Handler {
>
> private Function<IEclipseContext, MyDialog> dialogFactory =
> context -> ContextInjectionFactory.make(MyDialog.class,
> context);
>
> @Inject
> private IEventBroker eventBroker;
>
> private MyDialog myDialog;
>
> @Inject
> private MyService myService;
>
> private MessagingDelegate messagingDelegate;
>
> @Execute
> public void execute(IEclipseContext context) throws Exception {
>
> MyContext context = new MyContext();
>
> if (myDialog == null) {
> myDialog = dialogFactory.apply(context);
> }
>
> messagingDelegate.start(context.getQueueName(), message -> {
> eventBroker.post(EventConstants.TOPIC, message);
> });
>
> myService.start(context);
>
> myDialog.open();
>
> messagingDelegate.stop();
> }
>
> @Inject
> public void setMessagingDelegateFactory(MessagingDelegateFactory
> messagingDelegateFactory) {
> messagingDelegate =
> messagingDelegateFactory.createMessagingDelegate();
> }
> }
>
> The dialog implementation.
>
> package demo;
>
> import java.util.Objects;
>
> import javax.inject.Inject;
>
> import org.eclipse.e4.core.di.annotations.Optional;
> import org.eclipse.e4.core.services.nls.Translation;
> import org.eclipse.e4.ui.di.UIEventTopic;
> import org.eclipse.jface.dialogs.Dialog;
> import org.eclipse.jface.dialogs.IDialogConstants;
> import org.eclipse.jface.layout.GridDataFactory;
> import org.eclipse.jface.layout.GridLayoutFactory;
> import org.eclipse.swt.SWT;
> import org.eclipse.swt.events.SelectionAdapter;
> import org.eclipse.swt.events.SelectionEvent;
> import org.eclipse.swt.graphics.Point;
> import org.eclipse.swt.widgets.Button;
> import org.eclipse.swt.widgets.Composite;
> import org.eclipse.swt.widgets.Control;
> import org.eclipse.swt.widgets.Label;
> import org.eclipse.swt.widgets.ProgressBar;
> import org.eclipse.swt.widgets.Shell;
>
> public class MyDialog extends Dialog {
>
> @Inject
> @Optional
> public void notifyUpdate(@UIEventTopic(EventConstants.TOPIC)
> MyUpdate myUpdate) {
> if (myUpdate != null) {
> updateInformation(myUpdate);
> }
> }
>
> private void updateInformation(MyUpdate myUpdate) {
> label.setText(myUpdate.getInfo());
> }
> }
>
Previous Topic:eclipse rcp launcher
Next Topic:Using fragments
Goto Forum:
  


Current Time: Thu Apr 18 22:07:20 GMT 2024

Powered by FUDForum. Page generated in 0.01870 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top