Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [e4-dev] Dynamic Eclipse 4 with Clojure language

Current status:

I adopted the EventBroker + APP_STARTUP_COMPLETE option: In my Model
Processor class, I just register for the APP_STARTUP_COMPLETE event
and then in the callback function I dynamically modify the model like
this:

;; file ~/.ccw/script.clj
;; boring namespace declaration and imports omitted
(defn greet [context]
  (info-dialog "Hello world" "This popup provided to you from a user script"))

(defcommand greeter "Hello from CCW")

(defhandler greeter greet)

(defkeybinding greeter "Ctrl+Alt+Y")

The callback triggered from the APP_STARTUP_COMPLETE event localizes
user scripts in ~/.ccw and executes them.

The defcommand / defhandler / defkeybinding try as much as possible to
reuse existing commands/handlers/keybindings in the Model based on
identifiers (command, handler) or field values (keybinding).

The tag "ccw" is added to every command/handler/keybinding object
merged. There's also a randomUUID set as the value of the key
"ccw/load-key" in the Transient State.

Once the user script has been loaded, all
commands/handlers/keybindings in the Application Model with tag "ccw"
are gathered. Those that do not have a transient "ccw/load-key" key,
or a transient "ccw/load-key" key with the wrong value are removed
from the Application Model (the latter case is for being able to
live-reload the user scripts while developing, and still keeping the
Application Model clean).

Overall, works already quite well.

I thought this was the time to get some feedback from e4 experts on
what I already did.

I also have a question: I keep getting an exception stack trace, even
in the simplest scenario, while the user script starts.

I the simplest case, it happens when I only have (defcommand ...) and
(defhandler ...), even on a cleaned workspace + -clearPersistedState
option set.

I don't know what it means, and my mind isn't clear as to how I could
investigate more:

!ENTRY org.eclipse.equinox.event 4 0 2013-12-05 21:37:30.658

!MESSAGE Exception while dispatching event
org.osgi.service.event.Event
[topic=org/eclipse/e4/ui/model/application/Contribution/object/SET] to
handler org.eclipse.e4.ui.services.internal.events.UIEventHandler@7e11b954

!STACK 0

java.lang.ClassCastException:
org.eclipse.e4.ui.model.application.commands.impl.HandlerImpl cannot
be cast to org.eclipse.e4.ui.model.application.ui.MUIElement

at org.eclipse.ui.internal.WorkbenchPage$5.handleEvent(WorkbenchPage.java:4949)

at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:41)

at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:180)

at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:150)

at org.eclipse.swt.widgets.Display.syncExec(Display.java:4650)

at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:205)

at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:38)

at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:197)

at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197)

at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1)

at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)

at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148)

at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135)

at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78)

at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39)

at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:80)

at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:58)

at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374)

at org.eclipse.e4.ui.model.application.impl.ContributionImpl.setObject(ContributionImpl.java:131)

at org.eclipse.e4.ui.internal.workbench.addons.HandlerProcessingAddon.processActiveHandler(HandlerProcessingAddon.java:158)

at org.eclipse.e4.ui.internal.workbench.addons.HandlerProcessingAddon.access$0(HandlerProcessingAddon.java:151)

at org.eclipse.e4.ui.internal.workbench.addons.HandlerProcessingAddon$1.handleEvent(HandlerProcessingAddon.java:80)

at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:41)

at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:180)

at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:150)

at org.eclipse.swt.widgets.Display.syncExec(Display.java:4650)

at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:205)

at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:38)

at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:197)

at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197)

at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1)

at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)

at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148)

at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135)

at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78)

at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39)

at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:80)

at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:58)

at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374)

at org.eclipse.emf.ecore.util.EcoreEList.dispatchNotification(EcoreEList.java:249)

at org.eclipse.emf.common.notify.impl.NotifyingListImpl.addUnique(NotifyingListImpl.java:356)

at org.eclipse.emf.common.util.AbstractEList.add(AbstractEList.java:339)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:601)

at clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:93)

at clojure.lang.Reflector.invokeInstanceMethod(Reflector.java:28)

at ccw.util.e4.model$add_handler_BANG_.invoke(model.clj:653)

at ccw.util.e4.model$merge_handler_BANG_.invoke(model.clj:800)

at lein_script_test$fn__2851.invoke(script.clj:11)

at clojure.lang.AFn.applyToHelper(AFn.java:159)

at clojure.lang.AFn.applyTo(AFn.java:151)

at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3458)

at clojure.lang.Compiler$DefExpr.eval(Compiler.java:408)

at clojure.lang.Compiler.eval(Compiler.java:6624)

at clojure.lang.Compiler.load(Compiler.java:7064)

at clojure.lang.Compiler.loadFile(Compiler.java:7020)

at clojure.lang.RT$3.invoke(RT.java:318)

at ccw.core.user_plugins$start_user_plugins$fn__2833.invoke(user_plugins.clj:70)

at ccw.core.user_plugins$start_user_plugins.invoke(user_plugins.clj:69)

at clojure.lang.Var.invoke(Var.java:411)

at ccw.util.ClojureUtils.invoke(ClojureUtils.java:28)

at ccw.util.ClojureInvoker._(ClojureInvoker.java:18)

at ccw.core.Eclipse4ModelProcessor$1.handleEvent(Eclipse4ModelProcessor.java:45)

at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:41)

at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)

at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:135)

at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3976)

at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3653)

at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$9.run(PartRenderingEngine.java:1113)

at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)

at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:997)

at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:138)

at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:610)

at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)

at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:567)

at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:150)

at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:124)

at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)

at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)

at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)

at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:354)

at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:181)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:601)

at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:636)

at org.eclipse.equinox.launcher.Main.basicRun(Main.java:591)

at org.eclipse.equinox.launcher.Main.run(Main.java:1450)

at org.eclipse.equinox.launcher.Main.main(Main.java:1426)







2013/12/2 Laurent PETIT <laurent.petit@xxxxxxxxx>:
> Hey Paul,
>
> 2013/12/2 Paul Webster <pwebster@xxxxxxxxxxxxxxxxxxx>:
>> Hi Laurent,
>>
>> On Mon, Dec 2, 2013 at 8:04 AM, Laurent PETIT <laurent.petit@xxxxxxxxx>
>> wrote:
>>>
>>> I have considered it, not tried yet.
>>>
>>> So far, I have spotted in past discussions on the subject the
>>> following possibilities:
>>>
>>> 1/ EventBroker + APP_STARTUP_COMPLETE event => when to register to the
>>> EventBroker in the context of Eclipse the IDE? By doing it in my
>>> current Model Processor hook ?
>>
>>
>> Yes, we often use model processors to register for events (especially
>> related to model changes) for the application going forward.  This is the
>> Eclipse4 compatible approach.
>
> So I'll use this method, even if, as you pointed out, I will continue
> to live in a cross world between 3.x and 4.x APIs, since I won't be
> able to migrate all my code at once (and also I depend on so many
> things that are still stuck in the 3.x world, I guess ...)
>
>>
>>>
>>> 2/ Extend org.eclipse.ui.startup ? I have read that I am guaranteed
>>> that when my earlyStartup() method is called the Workbench is already
>>> totaly operational. But then how to get the MApplication instance?
>>> Currently I'm doing
>>>
>>> PlatformUI.getWorkbench().getService(IEclipseContext.class).get(MApplication.class).
>>
>>
>> If you use org.eclipse.ui.startup, you've picked the right pattern.  This is
>> based on 3.x (o.e.ui.startup is not part of Eclipse4) but if you need access
>> to things that need the Workbench, then you are tied to 3.x anyway.
>>
>>>
>>> 3/ Just use asyncExec on the display. But how to get the display instance?
>>
>>
>> If you are running in the IDE (which has the Workbench) this is the hardest
>> thing to get correct.  Calling Display.getDefault() can instantiate a
>> display on the incorrect thread and cause problems.  We use
>> org.eclipse.ui.IWorkbench.getDisplay() but that's then tied to 1) running
>> against the 3.x Workbench and 2) waiting until the workbench is up, which
>> happens after the model processor stuff is called.
>>
>>
>> Later,
>> Paul
>>
>>
>>
>> --
>> Paul Webster
>> Hi floor.  Make me a sammich! - GIR
>>
>> _______________________________________________
>> e4-dev mailing list
>> e4-dev@xxxxxxxxxxx
>> https://dev.eclipse.org/mailman/listinfo/e4-dev
>>


Back to the top