Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 374597 - [Compatibility] ClassCastException when adding pure 4.x view to 3.x perspective running in compatibility mode
Summary: [Compatibility] ClassCastException when adding pure 4.x view to 3.x perspecti...
Status: VERIFIED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 4.2   Edit
Hardware: All All
: P3 normal with 1 vote (vote)
Target Milestone: 4.2 M7   Edit
Assignee: Remy Suen CLA
QA Contact: Remy Suen CLA
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-03-18 04:53 EDT by Anders Forsell CLA
Modified: 2012-05-07 11:05 EDT (History)
3 users (show)

See Also:


Attachments
Git generated patch for the fix (1.02 KB, text/plain)
2012-03-18 10:25 EDT, Anders Forsell CLA
no flags Details
Patch (965 bytes, text/plain)
2012-03-19 09:50 EDT, Anders Forsell CLA
no flags Details
SimpleRCPApp project (96.52 KB, application/zip)
2012-03-19 18:57 EDT, Anders Forsell CLA
no flags Details
Remy's suggested fix (905 bytes, patch)
2012-03-20 02:33 EDT, Anders Forsell CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Anders Forsell CLA 2012-03-18 04:53:18 EDT
Build Identifier: 4.2M6

We are migrating an RCP application to 4.x and have to use the compatibility layer since we rely on a GEF editor. Several views can however be migrated to be "pure" 4.x views. I have found that I can add our clean parts as PartDescriptors in a customized "LegacyIDE.e4xmi". In the PerspectiveFactory I have also been able to add the view using IFolderLayout.addView(String idOfPurePart)

The problem I had to fix was that in WorkbenchPartReference.java (org.eclipse.ui.workbench) I had to check if the part is a compatibility part before the cast is done, see below for the change that fixes my problem:

			// check if we were actually created, it is insufficient to check
			// whether the 'object' feature is valid or not because it is one of
			// the last things to be unset during the teardown process, this
			// means we may return a valid workbench part even if it is actually
			// in the process of being destroyed, see bug 328944
			if (part.getWidget() != null) {
				Object object = part.getObject();
				if (object instanceof CompatibilityPart) {
					CompatibilityPart compatibilityPart = (CompatibilityPart) object;
					legacyPart = compatibilityPart.getPart();
				}
			}

I have seen this type of check in other parts of the e4 code.

Reproducible: Always
Comment 1 Remy Suen CLA 2012-03-18 05:50:27 EDT
Please attach a patch that contains your suggested fix.
Comment 2 Remy Suen CLA 2012-03-18 06:29:05 EDT
Please also attach the original exception that you were seeing before you changed WorkbenchPartReference.

It's not clear to me why what you describe is happening.
Comment 3 Anders Forsell CLA 2012-03-18 06:42:21 EDT
Here is the stack trace:

!ENTRY org.eclipse.ui 4 0 2012-03-18 11:40:03.272
!MESSAGE Unhandled event loop exception
!STACK 0
java.lang.ClassCastException: se.findout.priovis.editor.e4parts.CleanE4Part cannot be cast to org.eclipse.ui.internal.e4.compatibility.CompatibilityPart
	at org.eclipse.ui.internal.WorkbenchPartReference.getPart(WorkbenchPartReference.java:473)
	at org.eclipse.ui.internal.WorkbenchPage.findPart(WorkbenchPage.java:738)
	at org.eclipse.ui.internal.e4.compatibility.SelectionService.selectionChanged(SelectionService.java:321)
	at org.eclipse.gef.ui.parts.AbstractEditPartViewer.fireSelectionChanged(AbstractEditPartViewer.java:247)
	at org.eclipse.gef.ui.parts.AbstractEditPartViewer$1.run(AbstractEditPartViewer.java:131)
	at org.eclipse.gef.SelectionManager.fireSelectionChanged(SelectionManager.java:144)
	at org.eclipse.gef.SelectionManager.appendSelection(SelectionManager.java:83)
	at org.eclipse.gef.ui.parts.AbstractEditPartViewer.appendSelection(AbstractEditPartViewer.java:190)
	at org.eclipse.gef.ui.parts.AbstractEditPartViewer.select(AbstractEditPartViewer.java:599)
	at org.eclipse.gef.tools.SelectEditPartTracker.performSelection(SelectEditPartTracker.java:221)
	at org.eclipse.gef.tools.SelectEditPartTracker.performConditionalSelection(SelectEditPartTracker.java:167)
	at org.eclipse.gef.tools.SelectEditPartTracker.handleButtonDown(SelectEditPartTracker.java:92)
	at org.eclipse.gef.tools.AbstractTool.mouseDown(AbstractTool.java:1091)
	at org.eclipse.gef.tools.SelectionTool.mouseDown(SelectionTool.java:514)
	at org.eclipse.gef.EditDomain.mouseDown(EditDomain.java:245)
	at org.eclipse.gef.ui.parts.DomainEventDispatcher.dispatchMousePressed(DomainEventDispatcher.java:348)
	at org.eclipse.draw2d.LightweightSystem$EventHandler.mouseDown(LightweightSystem.java:523)
	at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:192)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
	at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4130)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1457)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1480)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1465)
	at org.eclipse.swt.widgets.Widget.notifyListeners(Widget.java:1270)
	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3976)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3615)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$9.run(PartRenderingEngine.java:1015)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:909)
	at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:85)
	at org.eclipse.ui.internal.Workbench$4.run(Workbench.java:580)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:535)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
	at se.findout.priovis.application.Application.start(Application.java:101)
	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:353)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:180)
	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:629)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:584)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1438)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1414)
Comment 4 Thomas Schindl CLA 2012-03-18 06:52:07 EDT
interesting that the live model view is not hit by this problem as well. The livemodel-bundle uses a processor to register a PartDescriptor
Comment 5 Anders Forsell CLA 2012-03-18 07:06:24 EDT
Hello Remy,

How do I create a patch correctly?
I tried cloning git://git.eclipse.org/gitroot/e4/eclipse.platform.ui.compat.git and imported org.eclipse.ui.workbench into my Workspace running Eclipse 4.2M6. However, I got a bunch of errors since the master/HEAD version doesn't seem to correspond to my running target platform. Also, I didn't find a command for creating a patch?

The way I handled and tested the change was to import the plug-in as a source project which I modified.

If you give some hints I can try to create a patch the correct way.

Regards,

Anders
Comment 6 Remy Suen CLA 2012-03-18 07:11:17 EDT
(In reply to comment #5)
> How do I create a patch correctly?
> I tried cloning git://git.eclipse.org/gitroot/e4/eclipse.platform.ui.compat.git
> and imported org.eclipse.ui.workbench into my Workspace running Eclipse 4.2M6.
> However, I got a bunch of errors since the master/HEAD version doesn't seem to
> correspond to my running target platform.

What kind of compiler errors did you get? There have been two commits since master was reopened. You may need to import some other projects.

http://git.eclipse.org/c/platform/eclipse.platform.ui.git/commit/?id=0deafb8a9de2273a12efb2e56c06e27872b6116c

http://git.eclipse.org/c/platform/eclipse.platform.ui.git/commit/?id=ff42387d247a1b1390c62f6f9983a9b35ff9f3ce
Comment 7 Paul Webster CLA 2012-03-18 07:37:29 EDT
(In reply to comment #5)
> I tried cloning git://git.eclipse.org/gitroot/e4/eclipse.platform.ui.compat.git

This is an old repo that hasn't been cleaned up yet.  Please use git://git.eclipse.org/gitroot/platform/eclipse.platform.ui.git

PW
Comment 8 Anders Forsell CLA 2012-03-18 10:25:42 EDT
Created attachment 212831 [details]
Git generated patch for the fix

I tried generating a patch according to http://wiki.eclipse.org/Git_for_Committers#Generating_patches_for_Bugzilla, see attachment.
Comment 9 Remy Suen CLA 2012-03-19 09:24:44 EDT
(In reply to comment #8)
> Created attachment 212831 [details]
> Git generated patch for the fix

I don't agree with this change. A pure Eclipse 4 part should not have an associated part reference. The perspective needs to be fixed so that it doesn't generate ViewReferences for pure 4.x parts.
Comment 10 Anders Forsell CLA 2012-03-19 09:50:38 EDT
Created attachment 212859 [details]
Patch

Added a better patch that have been created and used with EGit
Comment 11 Paul Webster CLA 2012-03-19 14:24:01 EDT
This will have to be deferred, we don't yet support hosting Eclipse4 parts in the 4.2 Workbench.

PW
Comment 12 Oleg Besedin CLA 2012-03-19 14:28:41 EDT
As a workaround, see ContextTraceLegacyView class in "org.eclipse.e4.core.contexts.debug" bundle, eclipse.platform.ui Git repo.

I've encountered similar problems while working on the context debug view and endded up making a "wrapper" ViewPart.

(While the proposed fix will stop the immediate exception, there are other places where things won't work or the functionality is still missing.)
Comment 13 Anders Forsell CLA 2012-03-19 16:39:29 EDT
(In reply to comment #12)
> As a workaround, see ContextTraceLegacyView class in
> "org.eclipse.e4.core.contexts.debug" bundle, eclipse.platform.ui Git repo.
> 
> I've encountered similar problems while working on the context debug view and
> endded up making a "wrapper" ViewPart.

This is very much like how it is done in the "forward compatibility layer" (by Tom S.)

> 
> (While the proposed fix will stop the immediate exception, there are other
> places where things won't work or the functionality is still missing.)

Can you elaborate some more where this won't work...
While we can live with the workaround for the time being, it would be interesting to know if you foresee any problem of having "pure" parts not added to the 3.x perspective, but rather added using the EPartServie.showPart instead?
The pure part can communicate through the selection service and we have seen that you can actually handle selection changes both ways 3.x <=> 4.x, thanks to a hint from Remy S.

(we are doing a talk on this topic next week at Eclipsecon, so your help is very appreciated  ;-)
Comment 14 Remy Suen CLA 2012-03-19 17:05:59 EDT
Anders, please provide some code and reproducible steps that will show the exception.

I do not like the suggested fix at the moment but I may be misunderstanding the root problem here.
Comment 15 Anders Forsell CLA 2012-03-19 18:57:08 EDT
Created attachment 212881 [details]
SimpleRCPApp project

This RCP application is based on the Mail demo example. I added the pure e4 part, see PureE4Part.java. A PartReference is added in the MyLegacyIDE.e4xmi (which is based on the LegacyIDE.e4xmi). In the Perspective class the pure e4 part is added.

Run the application making sure that the launch config has all the necessary bundles.

The same exception appears when closing the application (however a different stack trace), see below.

!ENTRY org.eclipse.ui.workbench 4 2 2012-03-19 23:46:27.094
!MESSAGE Problems occurred when invoking code from plug-in: "org.eclipse.ui.workbench".
!STACK 0
java.lang.ClassCastException: parts.PureE4Part cannot be cast to org.eclipse.ui.internal.e4.compatibility.CompatibilityPart
	at org.eclipse.ui.internal.WorkbenchPartReference.getPart(WorkbenchPartReference.java:473)
	at org.eclipse.ui.internal.ViewReference.getView(ViewReference.java:90)
	at org.eclipse.ui.internal.Workbench$14.run(Workbench.java:1068)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
	at org.eclipse.ui.internal.Workbench.busyClose(Workbench.java:1060)
	at org.eclipse.ui.internal.Workbench.access$15(Workbench.java:993)
	at org.eclipse.ui.internal.Workbench$16.run(Workbench.java:1174)
	at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
	at org.eclipse.ui.internal.Workbench.close(Workbench.java:1172)
	at org.eclipse.ui.internal.Workbench.close(Workbench.java:1145)
	at org.eclipse.ui.internal.WorkbenchWindow.busyClose(WorkbenchWindow.java:1155)
	at org.eclipse.ui.internal.WorkbenchWindow.access$16(WorkbenchWindow.java:1137)
	at org.eclipse.ui.internal.WorkbenchWindow$10.run(WorkbenchWindow.java:1184)
	at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
	at org.eclipse.ui.internal.WorkbenchWindow.close(WorkbenchWindow.java:1182)
	at org.eclipse.ui.internal.WorkbenchWindow.close(WorkbenchWindow.java:1194)
	at org.eclipse.ui.internal.WorkbenchWindow$6.close(WorkbenchWindow.java:439)
	at org.eclipse.e4.ui.workbench.renderers.swt.WBWRenderer$10.shellClosed(WBWRenderer.java:562)
	at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:98)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
	at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4130)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1457)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1480)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1465)
	at org.eclipse.swt.widgets.Shell.closeWidget(Shell.java:610)
	at org.eclipse.swt.widgets.Shell.windowShouldClose(Shell.java:2266)
	at org.eclipse.swt.widgets.Display.windowProc(Display.java:5460)
	at org.eclipse.swt.internal.cocoa.OS.objc_msgSendSuper(Native Method)
	at org.eclipse.swt.widgets.Widget.callSuper(Widget.java:220)
	at org.eclipse.swt.widgets.Widget.windowSendEvent(Widget.java:2095)
	at org.eclipse.swt.widgets.Shell.windowSendEvent(Shell.java:2262)
	at org.eclipse.swt.widgets.Display.windowProc(Display.java:5526)
	at org.eclipse.swt.internal.cocoa.OS.objc_msgSendSuper(Native Method)
	at org.eclipse.swt.widgets.Display.applicationSendEvent(Display.java:4976)
	at org.eclipse.swt.widgets.Display.applicationProc(Display.java:5125)
	at org.eclipse.swt.internal.cocoa.OS.objc_msgSend(Native Method)
	at org.eclipse.swt.internal.cocoa.NSApplication.sendEvent(NSApplication.java:128)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3612)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$9.run(PartRenderingEngine.java:1015)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:909)
	at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:85)
	at org.eclipse.ui.internal.Workbench$4.run(Workbench.java:580)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:535)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
	at simplercpapp.Application.start(Application.java:20)
	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:353)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:180)
	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:629)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:584)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1438)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1414)
Comment 16 Remy Suen CLA 2012-03-19 19:12:58 EDT
(In reply to comment #15)
> The same exception appears when closing the application (however a different
> stack trace), see below.

Thanks, Anders.

As I suspected, the problem is in the perspective code.

ModeledPageLayout's createViewModel(*) method is generating a ViewReference for 4.x parts. This is wrong. The code should look like this instead.

if (visible
    && createReferences
    &&
    CompatibilityView.COMPATIBILITY_VIEW_URI.equals(descriptor.getContributionURI())) {
  page.createViewReferenceForPart(part, id);
}
Comment 17 Anders Forsell CLA 2012-03-20 02:33:20 EDT
Created attachment 212897 [details]
Remy's suggested fix

Thanks Remy,

I tested the suggested fix (see new patch), and it works great!

Can you please consider this for inclusion in 4.2M7?
Comment 18 Remy Suen CLA 2012-03-26 21:25:34 EDT
Fix pushed to master.
http://git.eclipse.org/c/platform/eclipse.platform.ui.git/commit/?id=d1356b9683fbe950bc1e0bfb8a93d39dc6849a5a

Thank you for the bug report, Anders.
Comment 19 Eric Moffatt CLA 2012-05-07 11:05:21 EDT
Verified (visually) in I20120503-1800.