3) This issue relates to concurrent
List<IResolve> CatalogImpl.find(URL ) call.
This method is called from Layer.getGeoResources() when IGeoResource is not
yet created.
CatalogImpl.find(URL ) finds firstly in CONNECTED services, then in
NOTCONNECTED..
Imagine we have OracleServiceImpl and we have only CONNECTED or NOTCONNECTED
states. There is a map with 3 layers from Oracle database, so 3
IGeoResources are requested to be found in CatalogImpl simultaneously from
different threads during opening MapEditor with this map (initial call comes
from Layer.getGeoResources()).
Map:
Layer1 (IGeoResource1)
Layer2 (IGeoResource2)
Layer3 (IGeoResource3)
First attempt to get members of the service is a blocking call, especially
in case of database when DataStore is created. The concurrent call of
CatalogImpl.find(URL ) causes that sometimes IGeoResource is not found and
the Layer is marked as a broken. I thought because of tricky
CatalogImpl.find(URL ) algorithm, but seems it does not.
CatalogImpl.find(URL ) uses getChildById(..) method that iterates through
members. My suspicion falls onto OracleServiceImpl.members(..) method:
public List<OracleGeoResource> members( IProgressMonitor monitor )
throws IOException {
if(members == null){
rLock.lock();
try{
if(members == null){
getDS(monitor); // load ds
members = new LinkedList<OracleGeoResource>();
String[] typenames = ds.getTypeNames();
if(typenames!=null)
for(int i=0;i<typenames.length;i++){
members.add(new
OracleGeoResource(this,typenames[i]));
}
}
}finally{
rLock.unlock();
}
}
return members;
}
members list is created, but filled after ds.getTypeNames() that is a
time-consuming call. During this time OracleServiceImpl.members() from other
threads returns empty but already created List instance and the caller is
unable to find IGeoResource.
May be fix for members() method is a right solution of underlying problem?