Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 536921 - Workspace unstartable due to Display call not on main thread
Summary: Workspace unstartable due to Display call not on main thread
Status: RESOLVED WORKSFORME
Alias: None
Product: JDT
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 4.8   Edit
Hardware: PC All
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: JDT-UI-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 540316 (view as bug list)
Depends on:
Blocks:
 
Reported: 2018-07-11 12:09 EDT by Peter Kriens CLA
Modified: 2018-12-21 08:20 EST (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Peter Kriens CLA 2018-07-11 12:09:13 EDT
We have a workspace that after running an OSGi JUnit test can no longer be started. I've started Eclipse in debug and I consistently see that the JUnit plugin creates a Display error 22 ( Display must be created on main thread due to Cocoa restrictions.) This seems to pass through the JavaPlugin.

A possible cause is that we create a JUnit configuration (maybe wrong?) in bndtools for the test that JUnit tries to use. (The problem is initiated from setCodeassistFavoriteStaticMembers() so this does not seem that likely.)

I can create the situation consistently on this workspace. I really would like to know if bndtools has a bug that causes this so I'll help anyway I can to drill down this quite nasty bug.

It looks like that our bndtools 4.1 gets rid of the problem but since I've no idea why I still want to understand what's happening.

Display.error(int) line: 1090	
Display.createDisplay(DeviceData) line: 842	
Display.create(DeviceData) line: 825	
Display(Device).<init>(DeviceData) line: 129	
Display.<init>(DeviceData) line: 724	
Display.<init>() line: 715	
Display.getDefault() line: 1420	
PreferenceConverter.<clinit>() line: 94	
PreferenceConstants.initializeDefaultValues(IPreferenceStore) line: 3874	
JavaUIPreferenceInitializer.initializeDefaultPreferences() line: 35	
PreferenceServiceRegistryHelper$1.run() line: 298	
SafeRunner.run(ISafeRunnable) line: 42	
PreferenceServiceRegistryHelper.runInitializer(IConfigurationElement) line: 301	
PreferenceServiceRegistryHelper.applyRuntimeDefaults(String, WeakReference<Object>) line: 131	
PreferencesService.applyRuntimeDefaults(String, WeakReference<Object>) line: 372	
DefaultPreferences.applyRuntimeDefaults() line: 222	
DefaultPreferences.load() line: 276	
DefaultPreferences(EclipsePreferences).create(EclipsePreferences, String, Object) line: 367	
DefaultPreferences(EclipsePreferences).internalNode(String, boolean, Object) line: 620	
DefaultPreferences(EclipsePreferences).node(String) line: 763	
DefaultScope(AbstractScope).getNode(String) line: 38	
DefaultScope.getNode(String) line: 74	
ScopedPreferenceStore.getDefaultPreferences() line: 234	
ScopedPreferenceStore.getPreferenceNodes(boolean) line: 265	
ScopedPreferenceStore.internalGet(String) line: 413	
ScopedPreferenceStore.getBoolean(String) line: 353	
MembersOrderPreferenceCache.install(IPreferenceStore) line: 61	
JavaPlugin.start(BundleContext) line: 402	
BundleContextImpl$3.run() line: 779	
BundleContextImpl$3.run() line: 1	
AccessController.doPrivileged(PrivilegedExceptionAction<T>) line: not available [native method]	
BundleContextImpl.startActivator(BundleActivator) line: 772	
BundleContextImpl.start() line: 729	
EquinoxBundle.startWorker0() line: 1002	
EquinoxBundle$EquinoxModule.startWorker() line: 354	
EquinoxBundle$EquinoxModule(Module).doStart(Module$StartOptions...) line: 581	
EquinoxBundle$EquinoxModule(Module).start(Module$StartOptions...) line: 449	
SecureAction.start(Module, Module$StartOptions...) line: 468	
EclipseLazyStarter.postFindLocalClass(String, Class<?>, ClasspathManager) line: 114	
ClasspathManager.findLocalClass(String) line: 505	
EquinoxClassLoader(ModuleClassLoader).findLocalClass(String) line: 328	
BundleLoader.findLocalClass(String) line: 392	
SingleSourcePackage.loadClass(String) line: 36	
BundleLoader.findClassInternal(String, boolean) line: 466	
BundleLoader.findClass(String, boolean) line: 419	
BundleLoader.findClass(String) line: 411	
EquinoxClassLoader(ModuleClassLoader).loadClass(String, boolean) line: 150	
EquinoxClassLoader(ClassLoader).loadClass(String) line: 357	
JUnitPlugin.setCodeassistFavoriteStaticMembers() line: 219	
JUnitPlugin.start(BundleContext) line: 200	
BundleContextImpl$3.run() line: 779	
BundleContextImpl$3.run() line: 1	
AccessController.doPrivileged(PrivilegedExceptionAction<T>) line: not available [native method]	
BundleContextImpl.startActivator(BundleActivator) line: 772	
BundleContextImpl.start() line: 729	
EquinoxBundle.startWorker0() line: 1002	
EquinoxBundle$EquinoxModule.startWorker() line: 354	
EquinoxBundle$EquinoxModule(Module).doStart(Module$StartOptions...) line: 581	
EquinoxBundle$EquinoxModule(Module).start(Module$StartOptions...) line: 449	
ModuleContainer$ContainerStartLevel.incStartLevel(int, List<Module>, boolean) line: 1682	
ModuleContainer$ContainerStartLevel.incStartLevel(int, List<Module>) line: 1662	
ModuleContainer$ContainerStartLevel.doContainerStartLevel(Module, int, FrameworkListener...) line: 1624	
ModuleContainer$ContainerStartLevel.dispatchEvent(Module, FrameworkListener[], int, Integer) line: 1555	
ModuleContainer$ContainerStartLevel.dispatchEvent(Object, Object, int, Object) line: 1	
EventManager.dispatchEvent(Set<Entry<K,V>>, EventDispatcher<K,V,E>, int, E) line: 230	
EventManager$EventThread<K,V,E>.run() line: 340	



From the log

Caused by: org.eclipse.swt.SWTException: Invalid thread access
        at org.eclipse.swt.SWT.error(SWT.java:4552)
        at org.eclipse.swt.SWT.error(SWT.java:4467)
        at org.eclipse.swt.SWT.error(SWT.java:4438)
        at org.eclipse.swt.widgets.Display.error(Display.java:1090)
        at org.eclipse.swt.widgets.Display.createDisplay(Display.java:842)
        at org.eclipse.swt.widgets.Display.create(Display.java:825)
        at org.eclipse.swt.graphics.Device.<init>(Device.java:129)
        at org.eclipse.swt.widgets.Display.<init>(Display.java:724)
        at org.eclipse.swt.widgets.Display.<init>(Display.java:715)
        at org.eclipse.swt.widgets.Display.getDefault(Display.java:1420)
        at org.eclipse.jface.preference.PreferenceConverter.<clinit>(PreferenceConverter.java:94)
Comment 1 Jan Hendriks CLA 2018-07-12 02:19:15 EDT
I can confirm this issue in Linux, Photon Release (4.8.0) and bndtools 4.0.
A workaround in Linux is to start eclipse using the "-clean" flag.
With bndtools 4.1.0 (4.1.0.DEV-20180711) however, this problem no longer occurs.
Comment 2 Peter Kriens CLA 2018-07-12 02:43:38 EDT
Similar thing happened on Windows and Linux as well
Comment 3 Andrey Loskutov CLA 2018-07-12 03:00:01 EDT
(In reply to Peter Kriens from comment #2)
> Similar thing happened on Windows and Linux as well

If someone tries to access preferences for Java *UI* in a non-UI thread, before they are initialized, this will fail on any OS.

See JUnitPlugin.start() -> JUnitPlugin.setCodeassistFavoriteStaticMembers()

PreferenceConstants.getPreferenceStore().getDefaultString(PreferenceConstants.CODEASSIST_FAVORITE_STATIC_MEMBERS);

PreferenceConstants are triggering org.eclipse.jdt.ui activation etc.

The related JDT JUnit plugin tries to access Java UI preferences, which are initialized and fail to do so because not running in UI thread. Related change is bug 511443.
Comment 4 Peter Kriens CLA 2018-07-12 03:48:47 EDT
Andrey, is this initially triggered by something we do in Bndtools or is this all in the JDT? Bndtools is not on the stack trace but we could of course trigger the activation because we load classes, although I would expect to see some Bndtools classes also.

I traced class loading and could not find any class loaded from Bndtools. (Its bundles are 'resumed' though.)
Comment 5 Andrey Loskutov CLA 2018-07-12 04:32:09 EDT
(In reply to Peter Kriens from comment #4)
> Andrey, is this initially triggered by something we do in Bndtools or is
> this all in the JDT? Bndtools is not on the stack trace but we could of
> course trigger the activation because we load classes, although I would
> expect to see some Bndtools classes also.
> 
> I traced class loading and could not find any class loaded from Bndtools.
> (Its bundles are 'resumed' though.)

I have not insight how bndtools works, but I guess the launch config which is used/generated for bnd tools could have had wrong plugin activation list / order, so that JDT UI "happened" to be activated on the wrong path or too early, before workbench was started and initialized display. 

If Display.getDefault() creates a new instance NOT by the workbench, it usually means, workbench did not started before, which is bad for any UI plugin.

But I must confess, I have not debugged this and I also don't know if JUnitPlugin activation is expected to be that early (before workbench), or it is by design of the specific launch type you have.
Comment 6 Peter Kriens CLA 2018-07-12 04:45:34 EDT
If none of the bndtools classes is loaded before this happened, what could cause JUnit to be started too early?

I am not sure I follow about the launch order. This is the startup of standard Photon + Java IDE + Groovy + Bndtools which works fine until we do a debug and restart the IDE. 

Do you know what could influence the launch order?
Comment 7 Andrey Loskutov CLA 2018-10-19 16:37:49 EDT
*** Bug 540316 has been marked as a duplicate of this bug. ***
Comment 8 Andrey Loskutov CLA 2018-10-19 16:41:33 EDT
(In reply to Peter Kriens from comment #6)
> If none of the bndtools classes is loaded before this happened, what could
> cause JUnit to be started too early?
> 
> I am not sure I follow about the launch order. This is the startup of
> standard Photon + Java IDE + Groovy + Bndtools which works fine until we do
> a debug and restart the IDE. 
> 
> Do you know what could influence the launch order?

See bug 540316 comment 3.
Peter, is bnd somehow changes bundle activation defaults, may be for the tests? If yes, can it be that by mistake it changed the defaults of the running IDE, not of the test instance? This would explain why the junit plugin was activated way to early, here and in bug 540316.
Comment 9 Peter Kriens CLA 2018-10-21 11:49:05 EDT
bndtools does not change any ordering in Eclipse as far as I can see. I find it hard to imagine it would do anything with the Eclipse bundles since its launching is completely different from any Eclipse code base. It has its own model.
Comment 10 Andrey Loskutov CLA 2018-10-21 11:57:10 EDT
(In reply to Peter Kriens from comment #9)
> bndtools does not change any ordering in Eclipse as far as I can see. I find
> it hard to imagine it would do anything with the Eclipse bundles since its
> launching is completely different from any Eclipse code base. It has its own
> model.

So the  bnd launch configuration code is not related to PDE launch configs in any ways, does not use anything from PDE, etc? I just wonder if the bnd launch config code somehow managed to overwrite Eclipse configuration, may be by extending or reusing some of PDE code?
Comment 11 Jan Mosig CLA 2018-12-21 08:13:47 EST
I confirm, that this problem does not occur anymore with bnd 4.1.0.

See: https://github.com/bndtools/bnd/issues/2802#issuecomment-448578929