Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 319713 - org.eclipse.e4.ui.workbench has a dependency on SWT
Summary: org.eclipse.e4.ui.workbench has a dependency on SWT
Status: RESOLVED FIXED
Alias: None
Product: e4
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 0.9   Edit
Hardware: PC Mac OS X - Carbon (unsup.)
: P3 major (vote)
Target Milestone: 4.1 M6   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 319721 (view as bug list)
Depends on: 321995 322226 338559
Blocks:
  Show dependency tree
 
Reported: 2010-07-13 09:30 EDT by Thomas Schindl CLA
Modified: 2011-03-03 15:25 EST (History)
7 users (show)

See Also:


Attachments
patch (10.15 KB, patch)
2010-07-13 09:42 EDT, Thomas Schindl CLA
no flags Details | Diff
Patch (31.97 KB, patch)
2010-07-13 09:58 EDT, Thomas Schindl CLA
no flags Details | Diff
Patch (69.01 KB, patch)
2010-07-13 11:05 EDT, Thomas Schindl CLA
no flags Details | Diff
Patch (48.45 KB, patch)
2010-07-13 13:21 EDT, Thomas Schindl CLA
no flags Details | Diff
Patch including XWT (49.94 KB, patch)
2010-07-13 13:43 EDT, Thomas Schindl CLA
no flags Details | Diff
patch (50.20 KB, patch)
2010-07-13 14:11 EDT, Thomas Schindl CLA
no flags Details | Diff
work in progress (58.74 KB, patch)
2010-08-19 09:55 EDT, Thomas Schindl CLA
no flags Details | Diff
extracted SWT-Specific stuff (28.58 KB, application/zip)
2010-08-19 09:56 EDT, Thomas Schindl CLA
no flags Details
jface with removed binding stuff (24.51 KB, patch)
2010-08-20 07:03 EDT, Thomas Schindl CLA
no flags Details | Diff
Bundle with jface.core classes (15.74 KB, application/zip)
2010-08-20 07:04 EDT, Thomas Schindl CLA
no flags Details
Stacktrace of dieing SWT (53.61 KB, application/octet-stream)
2010-08-20 07:11 EDT, Thomas Schindl CLA
no flags Details
updated jface.core bundle (15.74 KB, application/zip)
2010-08-20 09:27 EDT, Thomas Schindl CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Schindl CLA 2010-07-13 09:30:49 EDT
ui.di has dependency because it holds UIEventObjectSupplier! ui.di has to be platform neutral and the code should be moved to org.eclipse.e4.ui.workbench.swt.

For me this is major bug because it violates our overall architecture to keep SWT-Related stuff in ui.workbench.swt!
Comment 1 Thomas Schindl CLA 2010-07-13 09:42:12 EDT
Created attachment 174142 [details]
patch
Comment 2 Thomas Schindl CLA 2010-07-13 09:58:09 EDT
*** Bug 319721 has been marked as a duplicate of this bug. ***
Comment 3 Thomas Schindl CLA 2010-07-13 09:58:59 EDT
Created attachment 174146 [details]
Patch

This address the complete problem of getting SWT dependencies in ui.workbench through dependencies
Comment 4 Thomas Schindl CLA 2010-07-13 10:05:06 EDT
and the saga continues with org.eclipse.e4.ui.workbench having a direct dependency on "org.eclipse.jface.bindings" and "org.eclipse.e4.ui.bindings"(=> depending once more on SWT)
Comment 5 Thomas Schindl CLA 2010-07-13 10:07:04 EDT
Updateting title! org.eclipse.e4.ui.workbench should be free of dependencies on SWT this has been one of the core design decision we've taken when designing e4 and it looks we are violating it all over the place
Comment 6 Thomas Schindl CLA 2010-07-13 10:13:18 EDT
It looks the only thing needed is to move E4CommandProcessor to ui.workbench.swt and we are done
Comment 7 Paul Webster CLA 2010-07-13 10:15:22 EDT
This is probably not something you can undo in RC2

PW
Comment 8 Thomas Schindl CLA 2010-07-13 10:35:33 EDT
I tend to agree (the risk and time to change it is probably too big) and I'm really sorry that I had not discovered such a major (it's probably not the right term but I don't know another one) design defect. 

For me this is really one of the worst things when looking at e4 from the none Eclipse 4.0 SDK developers point of view because it is simply violating the e4 design as I understood and promoted it the last 2 years.
Comment 9 Thomas Schindl CLA 2010-07-13 11:05:42 EDT
Created attachment 174161 [details]
Patch

This patch simply moves the E4CommandProcessor to SWT (this is not 100% ideal because one would have to reimplement the logic) but now ui.workbench once more has 0 dependencies on SWT/JFace
Comment 10 Thomas Schindl CLA 2010-07-13 13:21:44 EDT
Created attachment 174177 [details]
Patch

This patch follows another route for DI and Services because there the dependency on SWT is only there to sync with the Display-Loop but there's a much better possibility to do this using the Realm provided by Eclipse Databinding.

The command processor change is the same than before - I can only say that the workbench runs and behaves as expected, the ui-test pass with the realm fix and rcp applications like Contact-Demo are still working.
Comment 11 Thomas Schindl CLA 2010-07-13 13:23:29 EDT
Paul do you still think this is too risky? Anyone else? I can only once more say I'd really like to see this fixed
Comment 12 Boris Bokowski CLA 2010-07-13 13:33:49 EDT
I'm +1 on the goal (but haven't looked at the patch in detail).
Comment 13 Thomas Schindl CLA 2010-07-13 13:43:16 EDT
Created attachment 174183 [details]
Patch including XWT

updated to HEAD and included change for XWT
Comment 14 Oleg Besedin CLA 2010-07-13 14:05:40 EDT
(In reply to comment #10)
> Created an attachment (id=174177) [details]
> Patch
> This patch follows another route for DI and Services because there the
> dependency on SWT is only there to sync with the Display-Loop but there's a
> much better possibility to do this using the Realm provided by Eclipse
> Databinding.

I would be careful with that - there is a little piece of code in there trying to ensure that we pick up proper value for the Display. (For instance, that we don't try to create a new Display on shutdown.)

The Realm code will use something like SWTObservables.getRealm(Display) which might or might not perform similar checks. 

Bottom line, it all sounds good and makes sense, but I feel that at this point (2 weeks before the release) we should limit code changes to what is clearly necessary for the release. If we, say, had a demo running e4 in a non-SWT environment, then this change could be justified, but as it is... Myself, I'd leave it for after release.
Comment 15 Thomas Schindl CLA 2010-07-13 14:11:41 EDT
Created attachment 174194 [details]
patch

Paul said the previous patch breaks event ordering now it is done 100% at the same time id had been before.
Comment 16 Thomas Schindl CLA 2010-07-13 14:18:20 EDT
(In reply to comment #14)
> (In reply to comment #10)
> > Created an attachment (id=174177) [details] [details]
> > Patch
> > This patch follows another route for DI and Services because there the
> > dependency on SWT is only there to sync with the Display-Loop but there's a
> > much better possibility to do this using the Realm provided by Eclipse
> > Databinding.
> 
> I would be careful with that - there is a little piece of code in there trying
> to ensure that we pick up proper value for the Display. (For instance, that we
> don't try to create a new Display on shutdown.)
> 

I saw the code but Realm is not creating displays because it has one or not which is set on start up. It simply wraps the syncExec/asyncExec.

> The Realm code will use something like SWTObservables.getRealm(Display) which
> might or might not perform similar checks. 

The realm is created on start of the system with the display used by the application so there's no need for this Display checks found in the original code. If realm would broken all the renderes would be as well.

> 
> Bottom line, it all sounds good and makes sense, but I feel that at this point
> (2 weeks before the release) we should limit code changes to what is clearly
> necessary for the release. If we, say, had a demo running e4 in a non-SWT
> environment, then this change could be justified, but as it is... Myself, I'd
> leave it for after release.

I know and give up at this point - I have to confess that I'm a bit frustrate about myself (mostly) not having found out and us introducing such a fundamental design error.
Comment 17 Thomas Schindl CLA 2010-08-10 09:33:26 EDT
Paul - can we together look at the E4CommandProcessor because this look like a bit tricky to get right.
Comment 18 Paul Webster CLA 2010-08-11 12:42:06 EDT
(In reply to comment #17)
> Paul - can we together look at the E4CommandProcessor because this look like a
> bit tricky to get right.

Yes, over the next couple of weeks we need to go over the architecture, both high level and in specific places.

ex: commands should be UI free.  The bindings need to be processed at the UI level, and the implementation (EBindingService) will be tied to SWT/JFace.

PW
Comment 19 Thomas Schindl CLA 2010-08-11 14:27:47 EDT
(In reply to comment #18)
> (In reply to comment #17)
> > Paul - can we together look at the E4CommandProcessor because this look like a
> > bit tricky to get right.
> 
> Yes, over the next couple of weeks we need to go over the architecture, both
> high level and in specific places.
> 
> ex: commands should be UI free.  The bindings need to be processed at the UI
> level, and the implementation (EBindingService) will be tied to SWT/JFace.
> 

I've been start to experiment and making EBindingService free from JFace but showing interfaces in the API. Ideally we could have the EBindingService free and only the implementation is specific to the toolkit. Would this make sense?
Comment 20 Thomas Schindl CLA 2010-08-19 09:55:27 EDT
Created attachment 176992 [details]
work in progress

splitting ui.bindings in 2 pieces
Comment 21 Thomas Schindl CLA 2010-08-19 09:56:42 EDT
Created attachment 176993 [details]
extracted SWT-Specific stuff
Comment 22 Thomas Schindl CLA 2010-08-19 09:59:11 EDT
What about the idea of splitting up jface into 2 pieces:
a) jface.core: Generic stuff which does not need SWT (e.g. many of the binding base classes, IStructuredSelection, ...)

b) jface: SWT-Specific classes (viewers, ....), requires and reexports jface.core
Comment 23 Thomas Schindl CLA 2010-08-19 10:30:32 EDT
Looks like i'm too dumb to split JFace into 2 parts so that ui.bindings would only dependend on the none-swt specific core which holds:
* Binding
* Trigger
* TriggerSequence
when doing this my inner Eclipse dies somewhere in SWT :-(
Comment 24 Boris Bokowski CLA 2010-08-19 23:51:05 EDT
(In reply to comment #22)
> What about the idea of splitting up jface into 2 pieces:
> a) jface.core: Generic stuff which does not need SWT (e.g. many of the binding
> base classes, IStructuredSelection, ...)
> 
> b) jface: SWT-Specific classes (viewers, ....), requires and reexports
> jface.core

I am supportive of this, and ideally we'd be looking for other opportunities to split JFace. For example, the viewers package should be relatively easy to split off (but I haven't tried it).
Comment 25 Thomas Schindl CLA 2010-08-20 07:03:24 EDT
Created attachment 177078 [details]
jface with removed binding stuff

This patch removes Binding, Trigger, TriggerSequence from JFace
Comment 26 Thomas Schindl CLA 2010-08-20 07:04:05 EDT
Created attachment 177079 [details]
Bundle with jface.core classes

The classes from jface in their own bundle
Comment 27 Thomas Schindl CLA 2010-08-20 07:05:54 EDT
This works fine for e4-Applications like the Contacts-demo (I verified keybindings are still working) but when launching an inner Eclipse I get a core dump on OS-X somewhere inside SWT and I have no idea at all what wrong
Comment 28 Thomas Schindl CLA 2010-08-20 07:11:19 EDT
Created attachment 177080 [details]
Stacktrace of dieing SWT
Comment 29 Thomas Schindl CLA 2010-08-20 07:13:09 EDT
(In reply to comment #24)
> (In reply to comment #22)
> > What about the idea of splitting up jface into 2 pieces:
> > a) jface.core: Generic stuff which does not need SWT (e.g. many of the binding
> > base classes, IStructuredSelection, ...)
> > 
> > b) jface: SWT-Specific classes (viewers, ....), requires and reexports
> > jface.core
> 
> I am supportive of this, and ideally we'd be looking for other opportunities to
> split JFace. For example, the viewers package should be relatively easy to
> split off (but I haven't tried it).

Ok. I'll file an extra bug for this. Should we try to do it directly in 3.x or start create a 4.x branch and backport to 3.x when we are confident that we don't break things?
Comment 30 Thomas Schindl CLA 2010-08-20 07:29:43 EDT
Ok. I found the reason (doing this in 3.x gives me a real exception). The problem has something to do with OSGi/Equinox, the package split and package scoped methods

----------8<----------
!ENTRY org.eclipse.ui.workbench 4 2 2010-08-20 13:20:25.654
!MESSAGE Problems occurred when invoking code from plug-in: "org.eclipse.ui.workbench".
!STACK 0
java.lang.IllegalAccessError: tried to access method org.eclipse.jface.bindings.Binding.deletes(Lorg/eclipse/jface/bindings/Binding;)Z from class org.eclipse.jface.bindings.BindingManager
	at org.eclipse.jface.bindings.BindingManager.removeDeletions(BindingManager.java:1951)
	at org.eclipse.jface.bindings.BindingManager.computeBindings(BindingManager.java:520)
	at org.eclipse.jface.bindings.BindingManager.recomputeBindings(BindingManager.java:1757)
	at org.eclipse.jface.bindings.BindingManager.getActiveBindingsByParameterizedCommand(BindingManager.java:945)
	at org.eclipse.jface.bindings.BindingManager.getActiveBindingsFor(BindingManager.java:1160)
	at org.eclipse.jface.bindings.BindingManager.getActiveBindingsFor1(BindingManager.java:1209)
	at org.eclipse.jface.bindings.BindingManager.getBestActiveBindingFor(BindingManager.java:1274)
	at org.eclipse.jface.bindings.BindingManager.getBestActiveBindingFor(BindingManager.java:1264)
	at org.eclipse.jface.action.ExternalActionManager$CommandCallback.getAcceleratorText(ExternalActionManager.java:315)
	at org.eclipse.jface.action.ActionContributionItem.update(ActionContributionItem.java:798)
	at org.eclipse.jface.action.ActionContributionItem.fill(ActionContributionItem.java:342)
	at org.eclipse.jface.action.ToolBarManager.update(ToolBarManager.java:353)
	at org.eclipse.jface.action.ToolBarManager.createControl(ToolBarManager.java:111)
	at org.eclipse.jface.action.ToolBarContributionItem.fill(ToolBarContributionItem.java:192)
	at org.eclipse.jface.action.CoolBarManager.update(CoolBarManager.java:930)
	at org.eclipse.jface.action.CoolBarManager.createControl(CoolBarManager.java:247)
	at org.eclipse.jface.internal.provisional.action.CoolBarManager2.createControl2(CoolBarManager2.java:76)
	at org.eclipse.jface.window.ApplicationWindow.createCoolBarControl(ApplicationWindow.java:523)
	at org.eclipse.ui.internal.WorkbenchWindow.createDefaultContents(WorkbenchWindow.java:1063)
	at org.eclipse.ui.internal.WorkbenchWindowConfigurer.createDefaultContents(WorkbenchWindowConfigurer.java:623)
	at org.eclipse.ui.application.WorkbenchWindowAdvisor.createWindowContents(WorkbenchWindowAdvisor.java:268)
	at org.eclipse.ui.internal.WorkbenchWindow.createContents(WorkbenchWindow.java:1010)
	at org.eclipse.jface.window.Window.create(Window.java:431)
	at org.eclipse.ui.internal.Workbench$63.runWithException(Workbench.java:3589)
	at org.eclipse.ui.internal.StartupThreading$StartupRunnable.run(StartupThreading.java:31)
	at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
	at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:134)
	at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3586)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3279)
	at org.eclipse.ui.application.WorkbenchAdvisor.openWindows(WorkbenchAdvisor.java:803)
	at org.eclipse.ui.internal.Workbench$31.runWithException(Workbench.java:1566)
	at org.eclipse.ui.internal.StartupThreading$StartupRunnable.run(StartupThreading.java:31)
	at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
	at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:134)
	at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3586)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3279)
	at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2537)
	at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2427)
	at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:670)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:663)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
	at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:115)
	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:369)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:619)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:574)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1407)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1383)
----------8<----------

What we see here is a that a class in org.eclipse.jface tries to access a method (delete) in Binding (org.eclipse.jface.core) which is package-scoped and fails. I'm not sure whether this is by design or there's a bug in equinox?

Adding Tom Watson maybe he can clarify the situation from the equinox.
Comment 31 Thomas Schindl CLA 2010-08-20 07:37:39 EDT
Making "final boolean deletes(final Binding binding)" public makes things work but I'm not sure that's what we want.
Comment 32 Thomas Schindl CLA 2010-08-20 07:41:01 EDT
Paul - beside the pending problem of splitting JFace. Could you take a look at:
* patch in comment 20
* extracted new bundle in comment 21

So that e4 code is prepared to take advantage of the JFace split once we managed it?
Comment 33 Thomas Watson CLA 2010-08-20 09:16:22 EDT
(In reply to comment #30)
> Adding Tom Watson maybe he can clarify the situation from the equinox.

This is not a bug in equinox, this is how split packages work.  A properly "designed" split package (I'm not sure there is such a thing) has no package-level dependencies between the various parts of the split package.  When you split a package out into multiple parts each part is packaged in a different bundle.  In OSGi each bundle has its own class loader, the class loader is what the module layer is based on, so now each part is loaded with a different class loader.  Two classes do not have package level access to each other unless they are in the same package name AND they are loaded by the same class loader.

So you have to consider doing something else:

1) create some internal "API" which is x-friended to the other "part" so it can call into the non-API things it needs to
2) create new real API that can be used by the other "part"
3) use fragments to split your optional functionality out.  fragments use the same class loader as there host and will get package-level access.  I'm not sure this is a good idea though because there is no good way to declare a dependency on the fragment right now.
Comment 34 Thomas Schindl CLA 2010-08-20 09:26:01 EDT
(In reply to comment #33)
> (In reply to comment #30)
> > Adding Tom Watson maybe he can clarify the situation from the equinox.
> 
> This is not a bug in equinox, this is how split packages work.  A properly
> "designed" split package (I'm not sure there is such a thing) has no
> package-level dependencies between the various parts of the split package. 
> When you split a package out into multiple parts each part is packaged in a
> different bundle.  In OSGi each bundle has its own class loader, the class
> loader is what the module layer is based on, so now each part is loaded with a
> different class loader.  Two classes do not have package level access to each
> other unless they are in the same package name AND they are loaded by the same
> class loader.
> 

Ok thanks for confirming what I already expected.

> So you have to consider doing something else:
> 
> 1) create some internal "API" which is x-friended to the other "part" so it can
> call into the non-API things it needs to
> 2) create new real API that can be used by the other "part"

I think we can go with declaring the method in question as API by making it public.
Comment 35 Thomas Schindl CLA 2010-08-20 09:27:44 EDT
Created attachment 177092 [details]
updated jface.core bundle
Comment 36 Paul Webster CLA 2010-08-23 08:20:13 EDT
(In reply to comment #32)
> Paul - beside the pending problem of splitting JFace. Could you take a look at:
> * patch in comment 20
> * extracted new bundle in comment 21
> 
> So that e4 code is prepared to take advantage of the JFace split once we
> managed it?

-1 at this time.  It's not as simple as taking a couple of classes and just moving them.  Their are other parts of the binding system that would need to have their classes split into abstract and SWT specific parts (I believe) while maintaining their API-ness.  I think it's do-able, but it will require some design and test, and we have other priorities in the framework at the moment.

PW
Comment 37 Thomas Schindl CLA 2010-08-23 09:07:55 EDT
(In reply to comment #36)
> (In reply to comment #32)
> > Paul - beside the pending problem of splitting JFace. Could you take a look at:
> > * patch in comment 20
> > * extracted new bundle in comment 21
> > 
> > So that e4 code is prepared to take advantage of the JFace split once we
> > managed it?
> 
> -1 at this time.  It's not as simple as taking a couple of classes and just
> moving them.  Their are other parts of the binding system that would need to
> have their classes split into abstract and SWT specific parts (I believe) while
> maintaining their API-ness.  I think it's do-able, but it will require some
> design and test, and we have other priorities in the framework at the moment.
> 
> PW

So what's your take on fixing this design issue? I welcome everything that removes the dependency on SWT in workbench.ui.
Comment 38 Eric Moffatt CLA 2010-08-23 10:06:31 EDT
Tom, I agree that SWT has leaked into too many places in the code. The original intent of the PartRenderingEngine was to be 'agnostic' (i.e. not SWT specific) for example.

Could you build a list of where/why SWT is being accessed outside the rendering code ? We can go over this and perhaps come up with a slightly different packaging arrangement(I had a few cases where I couldn't set up my addons dependencies correctly precisely because of the .workbench dependency you mention).
Comment 39 Thomas Schindl CLA 2010-08-23 10:10:28 EDT
(In reply to comment #38)
> Tom, I agree that SWT has leaked into too many places in the code. The original
> intent of the PartRenderingEngine was to be 'agnostic' (i.e. not SWT specific)
> for example.
> 

I'm not concerned about the PartRenderingEngine because if someone wants to render in a different technology he/she simple has to invest into writing his/her own.

> Could you build a list of where/why SWT is being accessed outside the rendering
> code ? We can go over this and perhaps come up with a slightly different
> packaging arrangement(I had a few cases where I couldn't set up my addons
> dependencies correctly precisely because of the .workbench dependency you
> mention).

This is the only place left with an inappropriate dependency - which makes e4 only useable inconjunction with SWT. The other problems I identified are already fixed.
Comment 40 Thomas Schindl CLA 2010-09-09 09:36:27 EDT
one more thing I'm not sure of is do we really expect client code to directly using EBindingService. Should they not modify our Application-Model instead?
Comment 41 Thomas Schindl CLA 2010-12-14 03:53:02 EST
Paul - I think we can close this now that the stuff was added to the Addons and the bundle is free from SWT-Dependencies right?
Comment 42 Thomas Schindl CLA 2011-03-03 15:25:12 EST
this if fixed now