You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2017/05/05 09:27:22 UTC
svn commit: r1793992 -
/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/OsgiInstallerImpl.java
Author: cziegeler
Date: Fri May 5 09:27:22 2017
New Revision: 1793992
URL: http://svn.apache.org/viewvc?rev=1793992&view=rev
Log:
SLING-6831 : ConcurrentModificationException in OSGi Installer
Modified:
sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/OsgiInstallerImpl.java
Modified: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/OsgiInstallerImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/OsgiInstallerImpl.java?rev=1793992&r1=1793991&r2=1793992&view=diff
==============================================================================
--- sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/OsgiInstallerImpl.java (original)
+++ sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/OsgiInstallerImpl.java Fri May 5 09:27:22 2017
@@ -103,16 +103,16 @@ implements OsgiInstaller, ResourceChange
private final BundleContext ctx;
/** New clients are joining through this map. */
- private final Map<String, List<InternalResource>> newResourcesSchemes = new HashMap<String, List<InternalResource>>();
+ private final Map<String, List<InternalResource>> newResourcesSchemes = new HashMap<>();
/** New resources added by clients. */
- private final List<InternalResource> newResources = new LinkedList<InternalResource>();
+ private final List<InternalResource> newResources = new LinkedList<>();
/** Removed resources from clients. */
- private final Set<String> urlsToRemove = new HashSet<String>();
+ private final Set<String> urlsToRemove = new HashSet<>();
/** Update infos to process. */
- private final List<UpdateInfo> updateInfos = new ArrayList<OsgiInstallerImpl.UpdateInfo>();
+ private final List<UpdateInfo> updateInfos = new ArrayList<>();
/** Are the required services satisfied? */
private volatile boolean satisfied = false;
@@ -226,9 +226,9 @@ implements OsgiInstaller, ResourceChange
*/
private void init() {
// start service trackers
- this.factoryTracker = new SortingServiceTracker<InstallTaskFactory>(ctx, InstallTaskFactory.class.getName(), this);
- this.transformerTracker = new SortingServiceTracker<ResourceTransformer>(ctx, ResourceTransformer.class.getName(), this);
- this.updateHandlerTracker = new SortingServiceTracker<UpdateHandler>(ctx, UpdateHandler.class.getName(), null);
+ this.factoryTracker = new SortingServiceTracker<>(ctx, InstallTaskFactory.class.getName(), this);
+ this.transformerTracker = new SortingServiceTracker<>(ctx, ResourceTransformer.class.getName(), this);
+ this.updateHandlerTracker = new SortingServiceTracker<>(ctx, UpdateHandler.class.getName(), null);
this.factoryTracker.open();
this.transformerTracker.open();
this.updateHandlerTracker.open();
@@ -364,7 +364,7 @@ implements OsgiInstaller, ResourceChange
checkScheme(scheme);
List<InternalResource> createdResources = null;
if ( resources != null && resources.length > 0 ) {
- createdResources = new ArrayList<InternalResource>();
+ createdResources = new ArrayList<>();
for(final InstallableResource r : resources ) {
try {
final InternalResource rr = InternalResource.create(scheme, r);
@@ -412,7 +412,7 @@ implements OsgiInstaller, ResourceChange
synchronized ( this.resourcesLock ) {
if ( updatedResources != null && updatedResources.size() > 0 ) {
this.newResources.addAll(updatedResources);
- final Set<String> newUrls = new HashSet<String>();
+ final Set<String> newUrls = new HashSet<>();
for(final InternalResource rsrc : updatedResources) {
newUrls.add(rsrc.getURL());
}
@@ -426,7 +426,7 @@ implements OsgiInstaller, ResourceChange
}
}
if ( ids != null && ids.length > 0 ) {
- final Set<String> removedUrls = new HashSet<String>();
+ final Set<String> removedUrls = new HashSet<>();
for(final String id : ids) {
final String url = scheme + ':' + id;
// Will mark all resources which have r's URL as uninstallable
@@ -499,7 +499,7 @@ implements OsgiInstaller, ResourceChange
this.closeInputStreams(resources);
}
}
-
+
/** When a resource from "incoming" is about to replace "existing", we might need to transfer their private
* data file, or delete it if it's not needed anymore.
*/
@@ -520,14 +520,14 @@ implements OsgiInstaller, ResourceChange
break;
}
}
-
+
if(existing.getPrivateCopyOfFile() != null) {
logger.debug("Private data file not needed anymore, deleting it: {}", existing.getURL());
existing.getPrivateCopyOfFile().delete();
}
}
}
-
+
private void mergeNewlyRegisteredResources() {
synchronized ( this.resourcesLock ) {
for(final Map.Entry<String, List<InternalResource>> entry : this.newResourcesSchemes.entrySet()) {
@@ -541,7 +541,7 @@ implements OsgiInstaller, ResourceChange
for(final String entityId : this.persistentList.getEntityIds()) {
final EntityResourceList group = this.persistentList.getEntityResourceList(entityId);
- final List<TaskResource> toRemove = new ArrayList<TaskResource>();
+ final List<TaskResource> toRemove = new ArrayList<>();
boolean first = true;
for(final TaskResource r : group.listResources()) {
if ( r.getScheme().equals(scheme) ) {
@@ -639,7 +639,7 @@ implements OsgiInstaller, ResourceChange
* Compute OSGi tasks based on our resources, and add to supplied list of tasks.
*/
private SortedSet<InstallTask> computeTasks() {
- final SortedSet<InstallTask> tasks = new TreeSet<InstallTask>();
+ final SortedSet<InstallTask> tasks = new TreeSet<>();
// Walk the list of entities, and create appropriate OSGi tasks for each group
final List<InstallTaskFactory> services = this.factoryTracker.getSortedServices();
@@ -911,11 +911,13 @@ implements OsgiInstaller, ResourceChange
* @return <code>true</code> if another cycle should be started.
*/
private boolean cleanupInstallableResources() {
- final boolean result = this.persistentList.compact();
- this.persistentList.save();
- printResources("Compacted");
- logger.debug("cleanupInstallableResources returns {}", result);
- return result;
+ synchronized ( this.resourcesLock ) {
+ final boolean result = this.persistentList.compact();
+ this.persistentList.save();
+ printResources("Compacted");
+ logger.debug("cleanupInstallableResources returns {}", result);
+ return result;
+ }
}
/**
@@ -926,47 +928,49 @@ implements OsgiInstaller, ResourceChange
final List<ServiceReference> serviceRefs = this.transformerTracker.getSortedServiceReferences();
if ( serviceRefs.size() > 0 ) {
- // Walk the list of unknown resources and invoke all transformers
- int index = 0;
- final List<RegisteredResource> unknownList = this.persistentList.getUntransformedResources();
-
- while ( index < unknownList.size() ) {
- final RegisteredResource resource = unknownList.get(index);
- for(final ServiceReference reference : serviceRefs) {
- final Long id = (Long)reference.getProperty(Constants.SERVICE_ID);
- // check if this transformer has already been invoked for the resource
- final String transformers = (String)((RegisteredResourceImpl)resource).getAttribute(ResourceTransformer.class.getName());
- if ( id == null ||
- (transformers != null && transformers.contains(":" + id + ':'))) {
- continue;
- }
- final ResourceTransformer transformer = (ResourceTransformer) this.transformerTracker.getService(reference);
- if ( transformer != null ) {
- try {
- final TransformationResult[] result = transformer.transform(resource);
- final String newTransformers = (transformers == null ? ":" + id + ':' : transformers + id + ':');
- ((RegisteredResourceImpl)resource).setAttribute(ResourceTransformer.class.getName(), newTransformers);
- if ( logger.isDebugEnabled() ) {
- logger.debug("Invoked transformer {} on {} : {}",
- new Object[] {transformer, resource, Arrays.toString(result)});
- }
- if ( result != null && result.length > 0 ) {
- this.persistentList.transform(resource, result);
- changed = true;
- index--;
- break;
+ synchronized ( this.resourcesLock ) {
+ // Walk the list of unknown resources and invoke all transformers
+ int index = 0;
+ final List<RegisteredResource> unknownList = this.persistentList.getUntransformedResources();
+
+ while ( index < unknownList.size() ) {
+ final RegisteredResource resource = unknownList.get(index);
+ for(final ServiceReference reference : serviceRefs) {
+ final Long id = (Long)reference.getProperty(Constants.SERVICE_ID);
+ // check if this transformer has already been invoked for the resource
+ final String transformers = (String)((RegisteredResourceImpl)resource).getAttribute(ResourceTransformer.class.getName());
+ if ( id == null ||
+ (transformers != null && transformers.contains(":" + id + ':'))) {
+ continue;
+ }
+ final ResourceTransformer transformer = (ResourceTransformer) this.transformerTracker.getService(reference);
+ if ( transformer != null ) {
+ try {
+ final TransformationResult[] result = transformer.transform(resource);
+ final String newTransformers = (transformers == null ? ":" + id + ':' : transformers + id + ':');
+ ((RegisteredResourceImpl)resource).setAttribute(ResourceTransformer.class.getName(), newTransformers);
+ if ( logger.isDebugEnabled() ) {
+ logger.debug("Invoked transformer {} on {} : {}",
+ new Object[] {transformer, resource, Arrays.toString(result)});
+ }
+ if ( result != null && result.length > 0 ) {
+ this.persistentList.transform(resource, result);
+ changed = true;
+ index--;
+ break;
+ }
+ } catch (final Throwable t) {
+ logger.error("Uncaught exception during resource transformation!", t);
}
- } catch (final Throwable t) {
- logger.error("Uncaught exception during resource transformation!", t);
}
}
+ index++;
}
- index++;
}
- }
- if ( changed ) {
- this.persistentList.save();
- printResources("Transformed");
+ if ( changed ) {
+ this.persistentList.save();
+ printResources("Transformed");
+ }
}
}
@@ -1077,7 +1081,7 @@ implements OsgiInstaller, ResourceChange
* @see org.apache.sling.installer.api.ResourceChangeListener#resourceRemoved(java.lang.String, java.lang.String)
*/
private void processUpdateInfos() {
- final List<UpdateInfo> infos = new ArrayList<OsgiInstallerImpl.UpdateInfo>();
+ final List<UpdateInfo> infos = new ArrayList<>();
synchronized ( resourcesLock ) {
infos.addAll(updateInfos);
updateInfos.clear();
@@ -1360,9 +1364,9 @@ implements OsgiInstaller, ResourceChange
synchronized ( this.resourcesLock ) {
final InstallationState state = new InstallationState() {
- private final List<ResourceGroup> activeResources = new ArrayList<ResourceGroup>();
- private final List<ResourceGroup> installedResources = new ArrayList<ResourceGroup>();
- private final List<RegisteredResource> untransformedResources = new ArrayList<RegisteredResource>();
+ private final List<ResourceGroup> activeResources = new ArrayList<>();
+ private final List<ResourceGroup> installedResources = new ArrayList<>();
+ private final List<RegisteredResource> untransformedResources = new ArrayList<>();
@Override
public List<ResourceGroup> getActiveResources() {
@@ -1392,7 +1396,7 @@ implements OsgiInstaller, ResourceChange
final EntityResourceList group = this.persistentList.getEntityResourceList(entityId);
final String alias = group.getAlias();
- final List<Resource> resources = new ArrayList<Resource>();
+ final List<Resource> resources = new ArrayList<>();
boolean first = true;
boolean isActive = false;
for(final TaskResource tr : group.getResources()) {