Bug 202866 - [efs] ArrayIndexOutOfBounds in RSEFileSystemContributor.browseFileSystem()
Summary: [efs] ArrayIndexOutOfBounds in RSEFileSystemContributor.browseFileSystem()
Status: RESOLVED FIXED
Alias: None
Product: Target Management
Classification: Tools
Component: RSE (show other bugs)
Version: 2.0   Edit
Hardware: PC Mac OS X - Carbon (unsup.)
: P2 major (vote)
Target Milestone: 2.0.1   Edit
Assignee: Martin Oberhuber CLA
QA Contact: Martin Oberhuber CLA
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-09-10 19:17 EDT by Greg Watson CLA
Modified: 2007-09-11 12:28 EDT (History)
1 user (show)

See Also:
dmcknigh: review+


Attachments
Patch fixing the issue (4.17 KB, patch)
2007-09-11 10:57 EDT, Martin Oberhuber CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Greg Watson CLA 2007-09-10 19:17:52 EDT
If RSEFileSystemContributor.browseFileSystem() is the first method called (i.e. triggers the RSE plugins to load), it results in an ArrayIndexOutOfBounds exception. I looks to me like this is a race condition between the SystemRegistry getting populated and being used in SystemResourceSelectionInputProvider. The offending code is:

	public SystemResourceSelectionInputProvider()
	{
		// choose random host
		ISystemRegistry registry = RSECorePlugin.getTheSystemRegistry();
		IHost[] hosts = registry.getHosts();
		if (hosts != null)
			_connection = hosts[0];
	}

The assumption is made that hosts will contain at least one element (the Local host presumably), however the call to getHosts() actually returns an empty array. 

Tracing this back, it appears to be the result of SystemProfileManager.getActiveSystemProfiles()  returning an empty array. getActiveSystemProfiles() builds an ArrayList of active profiles from a private list _profiles, but if there are none it will return an empty array.

The simplest fix is to ensure that browseFileSystem() checks that the system registry is active:

boolean isRegistryActive = RSEUIPlugin.isTheSystemRegistryActive();
if (isRegistryActive) {
    Job[] jobs = Job.getJobManager().find(null);
    for(int i=0; i<jobs.length; i++) {
        if ("Initialize RSE".equals(jobs[i].getName())) { //$NON-NLS-1$
            //If still initializing, wait until done
            jobs[i].join();
            break;
        }
    }
}

However this is a risky approach as per bug #194802, since there is no guarantee that the thread that calls browseFileSystem() does not have locks on resources that RSE needs to start. This, along with all the other bugs relating to populating the registry (and other yet-to-be-found bugs), seem to be caused by the use of a thread to do the registry initialization. Perhaps it's time to think about changing this design decision?
Comment 1 Greg Watson CLA 2007-09-10 19:21:47 EDT
BTW, I've tested this code by adding it to the beginning of browseFileSystem() and it appears to fix my problem at least.
Comment 2 Martin Oberhuber CLA 2007-09-11 10:57:54 EDT
Created attachment 78070 [details]
Patch fixing the issue

Attached patch fixes the issue as follows:

* Fix the Exceptions in SystemResourceSelectionInputProvider, since it is a
  valid use-case to have no connections at all. The code must be prepared
  for that.
* Make the SystemResourceSelectionForm listen to systemRegistry change events.
  That way, if started during early init, the dialog comes up with an empty
  list first; but as soon as the init job is complete, SystemRegistry sends
  events to which the selection combo listens, so it fills itself
  asynchronously. That's fast enough for users not to notice.

By using asynchronous initialization, we can be sure not to run into any
deadlocks. I think that this is good enough for 2.0.1. 

In the longer run, I think we must avoid having client code to wait for SystemRegistry initialization. For TM 3.0, the following should be done:
 * Move SystemRegistry completely into non-UI and make it have minimal
   dependencies
 * Make the SystemRegistry Getters ensure that clients always get a fully 
   initialized registry. This will make the getters a little slower; but it
   ensures that no client needs to worry about not-yet-initialized registry.
   The Eclipse core.resources plugin is also working that way (i.e. 
   synchronous initialization only).
Comment 3 Martin Oberhuber CLA 2007-09-11 10:58:55 EDT
Dave can you please review the patch?
Comment 4 David McKnight CLA 2007-09-11 12:25:33 EDT
I haven't tested the patch, but the changes to the code look good.
Comment 5 Martin Oberhuber CLA 2007-09-11 12:28:12 EDT
Patch committed.

[202866] Fix exceptions in RSE browse dialog when SystemRegistry is not yet fully initialized