Bug 46438 - Ecliopse Hangs (Deadlock) on Startup
Summary: Ecliopse Hangs (Deadlock) on Startup
Status: RESOLVED DUPLICATE of bug 12827
Alias: None
Product: Platform
Classification: Eclipse Project
Component: Resources (show other bugs)
Version: 2.1.1   Edit
Hardware: Other HP-UX
: P3 critical (vote)
Target Milestone: ---   Edit
Assignee: Platform-Resources-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2003-11-11 17:06 EST by Michael Garvin CLA
Modified: 2003-11-12 11:16 EST (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Michael Garvin CLA 2003-11-11 17:06:07 EST
Hi, we implement an IDE for a proprietary language and source code versioning 
system, on top of Eclipse.  During the "early startup" of one of our plugins, 
we need to create a synthetic project.  This project is intented to wrap a 
directory on disk where source code from our proprietary versioning system is 
funelled through.  This normally works fine, except that sometimes after 
removing the runtime-workspace (or when starting from new), we are seeing a 
deadlock happen in the Eclipse code that created "projects".  

More specificly (defaultProject is our synthetic project):

. . . . . . . . . . . . . . . . . . . . . . 

if (!defaultProject.exists()) {

  // try to create a new project

  try {

    // create a project description and give it a builder...

    log("creating the project wrapper...");
 			
    IProjectDescription desc = 
        getWorkspace().newProjectDescription(DFLT_PROJECT);
	  
    desc.setLocation(null);
		
    log("Setting builder specification...");
	
    ICommand buildCmd = desc.newCommand();
    buildCmd.setBuilderName("CustomBuilderId");
	  
    String[] natureIds = {"customNature"};
	  
    ICommand[] buildCmds = new ICommand[1];
    buildCmds[0]=buildCmd;
	  
    desc.setBuildSpec(buildCmds);
	  
    log("Default Project now has a builder command.");

    // ok, now actually create the project!

    //
    // !! NOTE !!  I've noticed that sometimes on startup, this call to 
    // create the default project causes Eclipse to deadlock and the GUI
    // will freeze.  The only fix I've found so far far is to comment it out,
    // start Eclipse and then shutdown Eclipse.  Remove the comments,
    // and the start again.  After that the hangups disappear.  I think we may
    // eventually need to avoid creating projects at startup.
    //
    defaultProject.create(desc, null);
    defaultProject.open(null);

. . . . . . . . . . . . . . . . .  . . . . . 

Basicly when the early start method of our plugin is called, it falls through 
to calling defaultProject.create(desc,null); and somewhere inside the Eclipse 
code for creating a project, it just locks up.

Is there a way I can get around this?  Is it illegal to be creating project 
during plugin initialzation?  If so, are there some rules we can follow about 
accessing logical/physical resources during plugin initialization?

When we are developing the code, we can work around this issue by commenting 
in/out that "create" call, but once we deliver this to our internal customers, 
we won't have that luxury, it will need to work reliably all the time.

Let me know if you need a stack trace, or if you have any suggestion on how to 
rework or avoid the problem.

Thanks!
Comment 1 John Arthorne CLA 2003-11-11 18:26:57 EST
A stack trace illustrating the deadlock would be greatly appreciated.  On linux
this can generally be achieved by sending kill -3 to the java process.  Attach
the file to the bug report
Comment 2 Michael Garvin CLA 2003-11-12 10:03:08 EST
When I launch a workbench in the debugger with our plugins loaded, I just do 
a "suspend" in the debugger to see where the threads are blocked.  I 
think "Thread 1" is the problem, since its the thread were our plugin 
(PLSPlugin) runs:


System Thread [Finalizer] (Suspended)
	Object.wait(long) line: not available [native method]
	ReferenceQueue.remove(long) line: 111
	ReferenceQueue.remove() line: 127
	Finalizer$FinalizerThread.run() line: 159

System Thread [Reference Handler] (Suspended)
	Object.wait(long) line: not available [native method]
	Reference$Lock(Object).wait() line: 426
	Reference$ReferenceHandler.run() line: 113
	
Thread [main] (Suspended)
	Class.getDeclaredConstructors0(boolean) line: not available [native 
method]
	Class.privateGetDeclaredConstructors(boolean) line: 1590
	Class.getConstructor0(Class[], int) line: 1762
	Class.newInstance0() line: 276
	Class.newInstance() line: 259
	PluginDescriptor.createExecutableExtension(String, Object, 
IConfigurationElement, String) line: 138
	PluginDescriptor.createExecutableExtension(String, String, Object, 
IConfigurationElement, String) line: 167
	ConfigurationElement.createExecutableExtension(String) line: 103
	WorkbenchPlugin.createExtension(IConfigurationElement, String) line: 151
	WWinPluginAction(PluginAction).createDelegate() line: 103
	WWinPluginAction.refreshActionList() line: 148
	Workbench.refreshPluginActions(String) line: 1668
	AbstractUIPlugin$3.run() line: 746
	RunnableLock.run() line: 35
	UISynchronizer(Synchronizer).runAsyncMessages() line: 98
	Display.runAsyncMessages() line: 1936
	Display.readAndDispatch() line: 1727
	Workbench.runEventLoop(Window$IExceptionHandler) line: 1402
	Workbench.run(Object) line: 1385
	InternalBootLoader.run(String, URL, String, String[], Runnable) line: 
858
	BootLoader.run(String, URL, String, String[], Runnable) line: 461
	NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not 
available [native method]
	NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
	DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25
	Method.invoke(Object, Object[]) line: 324
	Main.basicRun(String[]) line: 291
	Main.run(String[]) line: 747
	Main.main(String[]) line: 583
	
System Thread [Signal Dispatcher] (Suspended)

Thread [Thread-1] (Suspended)
	Object.wait(long) line: not available [native method]
	Semaphore(Object).wait() line: 426
	Semaphore.acquire() line: 26
	UISynchronizer.syncExec(Runnable) line: 40
	Display.syncExec(Runnable) line: 2317
	WorkbenchContentProvider.resourceChanged(IResourceChangeEvent) line: 198
	NotificationManager$1.run() line: 137
	InternalPlatform.run(ISafeRunnable) line: 1006
	Platform.run(ISafeRunnable) line: 413
	NotificationManager.notify(ResourceChangeListenerList$ListenerEntry[], 
IResourceChangeEvent, boolean) line: 152
	NotificationManager.broadcastChanges(ElementTree, int, boolean, 
boolean) line: 67
	Workspace.broadcastChanges(ElementTree, int, boolean, boolean, 
IProgressMonitor) line: 161
	Workspace.endOperation(boolean, IProgressMonitor) line: 892
	Project.create(IProjectDescription, IProgressMonitor) line: 259
	PLSPlugin.earlyStartup() line: 383
	PLSPlugin.<init>(IPluginDescriptor) line: 115
	NativeConstructorAccessorImpl.newInstance0(Constructor, Object[]) line: 
not available [native method]
	NativeConstructorAccessorImpl.newInstance(Object[]) line: 39
	DelegatingConstructorAccessorImpl.newInstance(Object[]) line: 27
	Constructor.newInstance(Object[]) line: 274
	PluginDescriptor.internalDoPluginActivation() line: 722
	PluginDescriptor.doPluginActivation() line: 188
	PluginClassLoader.activatePlugin(String) line: 112
	PluginClassLoader.internalFindClassParentsSelf(String, boolean, 
DelegatingURLClassLoader, boolean) line: 185
	PluginClassLoader(DelegatingURLClassLoader).findClassParentsSelf
(String, boolean, DelegatingURLClassLoader, boolean) line: 485
	PluginClassLoader(DelegatingURLClassLoader).loadClass(String, boolean, 
DelegatingURLClassLoader, Vector, boolean) line: 882
	DelegatingURLClassLoader.access$0(DelegatingURLClassLoader, String, 
boolean, DelegatingURLClassLoader, Vector, boolean) line: 876
	DelegatingURLClassLoader$DelegateLoader.loadClass(String, 
DelegatingURLClassLoader, DelegatingURLClassLoader, Vector) line: 90
	PluginClassLoader(DelegatingURLClassLoader).findClassPrerequisites
(String, DelegatingURLClassLoader, Vector) line: 554
	PluginClassLoader(DelegatingURLClassLoader).loadClass(String, boolean, 
DelegatingURLClassLoader, Vector, boolean) line: 890
	PluginClassLoader(DelegatingURLClassLoader).loadClass(String, boolean) 
line: 862
	PluginClassLoader(ClassLoader).loadClass(String) line: 255
	PluginClassLoader(ClassLoader).loadClassInternal(String) line: 315
	ProtelEditorPlugin.earlyStartup() line: 359
	Workbench$15.run() line: 1327
	InternalPlatform.run(ISafeRunnable) line: 1006
	Platform.run(ISafeRunnable) line: 413
	Workbench$14.run() line: 1334
	Thread.run() line: 536

In the early setup of our plugin (Thread 1) you can see that its falling though 
to a semaphore somewhere inside Eclipse.  This makes me suspect that its bad 
idea to create projects during plugin initialization?  

NOTE: I can reproduce this problem very reliably by just moving my existing 
runtime-workspace out of the way.  Its only when we make this call to create a 
project that the deadlock happens.



Comment 3 Michael Garvin CLA 2003-11-12 10:05:16 EST
I just noticed through Thread 1, that our editor plgin's early startup code is 
wrapping the early startup code for our other plugin (the one that tries to 
create the project).  Is it possible that the editor plugin as a "lock" on the 
workspace and that is causing the deadlock?

Comment 4 John Arthorne CLA 2003-11-12 11:16:39 EST
This is what is happening.  PLSPlugin.earlyStartup is being called from within
the scope of a class loader.  This means Thread1 has a lock on the class loader
instance.  It then tries to do a syncExec (as a side-effect of project
creation), which requires synchronizing with the UI thread.  The UI thread is
currently trying to load a class in the same plugin, so it is blocked on the
class loader lock.

Unfortunately this is a well known problem with plugin startup (See "Note 3" in
the javadoc for Plugin.startup).  Doing anything that requires locks is going to
be risky.  I recommend minimizing the work done from within the startup method.
 In the worst case, you can try forking a thread at the end of your startup
method that does more complex startup work.

*** This bug has been marked as a duplicate of 12827 ***