Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 313426

Summary: Different instances of FormColors return the same Color objects causing SWT errors on disposal
Product: [Eclipse Project] Platform Reporter: Justin Dolezy <justin>
Component: User AssistanceAssignee: platform-ua-inbox <platform-ua-inbox>
Status: RESOLVED INVALID QA Contact:
Severity: major    
Priority: P3 CC: caniszczyk, cgold
Version: 3.4   
Target Milestone: ---   
Hardware: All   
OS: All   
Whiteboard:
Attachments:
Description Flags
Test case showing different FormColor instances now returning the same Color objects none

Description Justin Dolezy CLA 2010-05-18 15:11:42 EDT
Build Identifier: I20100312-1448

I'm moving my platform from 3.4.x to 3.6 and have been having an issue with disposed Color objects being used, causing IllegalArgumentExceptions etc.

I've tracked the problem down to FormColors, which in 3.4 different instances of this object would return different Color instances for the same given RGB. However in 3.5 FormColors was changed to use the LocalResourceManager, which now dished out the same Color intances across different FormColor instances [https://bugs.eclipse.org/bugs/show_bug.cgi?id=236418]

This means that it's no longer safe to dispose Colors created via createColor on one instance as it could well have been handed out by another instance (due to LRM delegating to JFaceResources).

My particular issue occurs due to the tabbed properties view class allocating colors via a FormColors object, and later disposing it. I have a custom tabbed properties view so I haven't tried replicating this on a "standard" implementation (is there one in the IDE?) - but if I open my GEF editor with the tabbed props view open, then another, when I close the second I get exceptions on painting of the first instance:

java.lang.IllegalArgumentException: Argument not valid
	at org.eclipse.swt.SWT.error(SWT.java:4064)
	at org.eclipse.swt.SWT.error(SWT.java:3998)
	at org.eclipse.swt.SWT.error(SWT.java:3969)
	at org.eclipse.swt.graphics.GC.setForeground(GC.java:3010)
	at org.eclipse.ui.internal.views.properties.tabbed.view.TabbedPropertyList$BottomNavigationElement.paint(TabbedPropertyList.java:446)
	at org.eclipse.ui.internal.views.properties.tabbed.view.TabbedPropertyList$BottomNavigationElement.access$0(TabbedPropertyList.java:434)
	at org.eclipse.ui.internal.views.properties.tabbed.view.TabbedPropertyList$7.paintControl(TabbedPropertyList.java:409)
	at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:217)


I'll attach a very simple test case which passes when run against a 3.4 target but not against 3.6, and presumably neither against 3.5.

Reproducible: Always
Comment 1 Justin Dolezy CLA 2010-05-18 15:14:00 EDT
Created attachment 169001 [details]
Test case showing different FormColor instances now returning the same Color objects
Comment 2 Prakash Rangaraj CLA 2010-05-19 01:15:00 EDT
The javadoc of createColor says: "Creates the color for the specified key using the provided RGB object. The color object will be returned and also put into the registry. When the class is disposed, the color will be disposed with it." 

So you shouldn't be disposing it. As a simple rule, you dispose only the items that you create (using new Color() or new Font() etc) if its created by other classes, the onus is on that other class to dispose it.

I'm assigning to UA for comments
Comment 3 Justin Dolezy CLA 2010-05-19 03:16:10 EDT
Thanks Prakash, seems like this is turning into "User Error". I'll repeat the mantra "if I new'd the resource, then I dispose the resource"... must working whilst too tired to have managed to dislodge that :)
Comment 4 Chris Goldthorpe CLA 2010-05-19 10:34:15 EDT
Prakash is correct, colors created by FormColors are reused and you should not call dispose on them. When FormColors is disposed it will also dispose of any colors it has created.