Community
Participate
Working Groups
Build ID: I20070625-1500 The basic situation has already been reported in bug 170030: it's a special kind of racing regarding the initialization of the instance location (please see bug 170030 for call chains). I now stumbled over a very simple way to reproduce this behavior without using any of the adaptor hooks (so please don't again wave your hands "you're completely on your own risk" ;-) I have a plug-in that uses a type from org.eclipse.core.resources. E.g., the activator of the plug-in instantiates a subtype of IWorkspaceRunnable (let's say for later use). To make it real fun, you could even declare your activator to implement IWorkspaceRunnable. If this plug-in gets activated during framework start and before IDEApplication.run() the transitively invoked activator of org.eclipse.core.resources initializes the instance location to its default. Ergo: the ChooseWorkspaceSelectionDialog will *never* be displayed because the location is already set before IDEApplication has a chance to get involved. IMHO this racing should not be determined by the accidental fact who comes first, core.resources or ide.application, but there must be a way to specify this. Perhaps ide.application should have a start level lower than the start level of core.resources AND any third-party plug-ins, if that's possible? Or could core.resources open the workspace more lazily?
> If this plug-in gets activated during framework start and before IDEApplication.run() How does this happen, out of curiosity? Can you give a stack trace of the activation in your case?
Re comment 1: the stack trace is pretty straight-forward: Daemon Thread [Start Level Event Dispatcher] (Suspended (breakpoint at line 355 in ResourcesPlugin)) ResourcesPlugin.start(BundleContext) line: 355 BundleContextImpl$2.run() line: 999 AccessController.doPrivileged(PrivilegedExceptionAction<T>) line: not available [native method] BundleContextImpl.startActivator(BundleActivator) line: 993 BundleContextImpl.start() line: 974 BundleHost.startWorker(int) line: 346 BundleHost(AbstractBundle).start(int) line: 260 SecureAction.start(Bundle, int) line: 400 EclipseLazyStarter.postFindLocalClass(String, Class, ClasspathManager) line: 111 ClasspathManager.findLocalClass(String) line: 417 DefaultClassLoader.findLocalClass(String) line: 189 BundleLoader.findLocalClass(String) line: 340 SingleSourcePackage.loadClass(String) line: 37 BundleLoader.findClassInternal(String, boolean, ClassLoader) line: 416 BundleLoader.findClass(String, boolean) line: 380 BundleLoader.findClass(String) line: 368 DefaultClassLoader.loadClass(String, boolean) line: 83 DefaultClassLoader(ClassLoader).loadClass(String) line: 251 DefaultClassLoader(ClassLoader).loadClassInternal(String) line: 319 ClassLoader.defineClass1(String, byte[], int, int, ProtectionDomain, String) line: not available [native method] DefaultClassLoader(ClassLoader).defineClass(String, byte[], int, int, ProtectionDomain) line: 620 DefaultClassLoader.defineClass(String, byte[], ClasspathEntry, BundleEntry) line: 161 ClasspathManager.defineClass(String, byte[], ClasspathEntry, BundleEntry, ClassLoadingStatsHook[]) line: 501 ClasspathManager.findClassImpl(String, ClasspathEntry, ClassLoadingStatsHook[]) line: 471 ClasspathManager.findLocalClassImpl(String, ClassLoadingStatsHook[]) line: 430 ClasspathManager.findLocalClass(String) line: 413 DefaultClassLoader.findLocalClass(String) line: 189 BundleLoader.findLocalClass(String) line: 340 BundleLoader.findClassInternal(String, boolean, ClassLoader) line: 419 BundleLoader.findClass(String, boolean) line: 380 BundleLoader.findClass(String) line: 368 DefaultClassLoader.loadClass(String, boolean) line: 83 DefaultClassLoader(ClassLoader).loadClass(String) line: 251 DefaultClassLoader(ClassLoader).loadClassInternal(String) line: 319 Activator.<init>() line: 28 NativeConstructorAccessorImpl.newInstance0(Constructor, Object[]) line: not available [native method] NativeConstructorAccessorImpl.newInstance(Object[]) line: 39 DelegatingConstructorAccessorImpl.newInstance(Object[]) line: 27 Constructor<T>.newInstance(Object...) line: 513 Class<T>.newInstance0() line: 355 Class<T>.newInstance() line: 308 BundleHost(AbstractBundle).loadBundleActivator() line: 136 BundleContextImpl.start() line: 970 BundleHost.startWorker(int) line: 346 BundleHost(AbstractBundle).resume() line: 350 Framework.resumeBundle(AbstractBundle) line: 1118 StartLevelManager.resumeBundles(AbstractBundle[], boolean) line: 634 StartLevelManager.incFWSL(int, AbstractBundle) line: 508 StartLevelManager.doSetStartLevel(int, AbstractBundle) line: 282 StartLevelManager.dispatchEvent(Object, Object, int, Object) line: 468 EventManager.dispatchEvent(EventListeners$ListElement[], EventDispatcher, int, Object) line: 195 EventManager$EventThread.run() line: 297 Activator.<init>() is the start of my plug-in, ResourcesPlugin.start() is the call that initializes the instance location.
Created attachment 79858 [details] Plug-in that reproduces this bug While trying to make this bug fully reproduceable I found that deleting org.eclipse.osgi/ from the configuration area made the bug disappear. So I created a minimal scenario that creates the situation I had in my configuration are. I created a new plug-in using the wizard for "Hello, World" and made minimal additions (in the sources marked as "added for Bug 204829"). now: + create a launch configuration for a runtime workbench including the plug-in Bug204829 + clear the input field "Workspace Data / Location" + launch, you will be asked for a workspace location + click the Sample button to see the message "Hello, Eclipse world" + close the workbench + re-launch: no-more workspace selection The essence is: once bundle.start() ( == start(0)) has ever been called for an installation, the given bundle will be activated eagerly before IDEApplication. So, basically, everything that makes activation of a plug-in permanent will probably create this situation. The more I think about this, the more natural it feels to have an extension point in the resources plug-in s.t. like InstanceLocationProvider: If no extension is found use the default, otherwise ask the provider. This could even be used by a client plug-in to provide arbitrary strategies for organizing multiple workspaces ;-) Or is it against the current policy to load extensions this early-up? Is there anything else that IDEApplication needs to do before any client plug-ins are activated? But then permanent/eager activation should probably be banned alltogether, right?
Persistently marking your bundle as started is generally not recommended, since it thwarts the platform's lazy activation mechanism. Generally you should call Bundle.start(Bundle.START_ACTIVATION_POLICY) to indicate that the bundle's activation policy should be used (typically the activation policy is lazy-start). Your point is well taken though, that the setting of the instance location is brittle.
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.