Author: jwross
Date: Thu Oct 11 00:19:39 2012
New Revision: 1396873
URL: http://svn.apache.org/viewvc?rev=1396873&view=rev
Log:
Fixed a deadlock and some CT failures.
A deadlock existed between org.eclipse.osgi.internal.resolver.StateImpl.monitor
and org.apache.aries.subsystem.core.Activator. It occurred when one thread was
initializing the root subsystem, had a lock on the Activator, and needed a lock
on the monitor as part of installing the region context bundle. Another thread
was loading a class with dynamic imports, kicked off a resolution that grabbed
the monitor lock, and ended up calling the SubsystemResolverHook which needed a
lock on the Activator. The fix was to remove the need for the Activator lock in
the SubsystemResolverHook.
1LKDEADLOCK Deadlock detected !!!
NULL ---------------------
NULL
2LKDEADLOCKTHR Thread "RMI TCP Connection(1)-127.0.0.1" (0x00007F19AC006F00)
3LKDEADLOCKWTR is waiting for:
4LKDEADLOCKMON sys_mon_t:0x00007F199C018240 infl_mon_t: 0x00007F199C0182B0:
4LKDEADLOCKOBJ
org/apache/aries/subsystem/core/internal/Activator@0x00007F19FD746DB8/0x00007F19FD746DD0:
3LKDEADLOCKOWN which is owned by:
2LKDEADLOCKTHR Thread "Blueprint Extender: 1" (0x00007F19A855BD00)
3LKDEADLOCKWTR which is waiting for:
4LKDEADLOCKMON sys_mon_t:0x00007F199C018380 infl_mon_t: 0x00007F199C0183F0:
4LKDEADLOCKOBJ java/lang/Object@0x00007F19FD40ED60/0x00007F19FD40ED78:
3LKDEADLOCKOWN which is owned by:
2LKDEADLOCKTHR Thread "RMI TCP Connection(1)-127.0.0.1" (0x00007F19AC006F00)
Also fixed some CT failures caused by the
org.apache.aries.subsystem.core.Location class. The location string can be
anything so we must handle it rather than throwing an exception.
Modified:
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Activator.java
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Location.java
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResolverHook.java
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResolverHookFactory.java
aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/RootSubsystemTest.java
Modified:
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Activator.java
URL:
http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Activator.java?rev=1396873&r1=1396872&r2=1396873&view=diff
==============================================================================
---
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Activator.java
(original)
+++
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Activator.java
Thu Oct 11 00:19:39 2012
@@ -153,8 +153,6 @@ public class Activator implements Bundle
instance = Activator.this;
}
registerBundleEventHook();
-
registrations.add(bundleContext.registerService(ResolverHookFactory.class, new
SubsystemResolverHookFactory(), null));
- registrar = new SubsystemServiceRegistrar(bundleContext);
try {
subsystems = new Subsystems();
}
@@ -164,6 +162,8 @@ public class Activator implements Bundle
catch (Exception e) {
throw new SubsystemException(e);
}
+
registrations.add(bundleContext.registerService(ResolverHookFactory.class, new
SubsystemResolverHookFactory(subsystems), null));
+ registrar = new SubsystemServiceRegistrar(bundleContext);
AriesSubsystem root = subsystems.getRootSubsystem();
root.start();
}
@@ -263,8 +263,8 @@ public class Activator implements Bundle
activate();
}
}
- else if (service instanceof IDirectoryFinder)
- finders.add((IDirectoryFinder)service);
+ else if (service instanceof IDirectoryFinder)
+ finders.add((IDirectoryFinder)service);
else
repositories.add((Repository)service);
return service;
@@ -304,13 +304,13 @@ public class Activator implements Bundle
else if (service instanceof ModelledResourceManager) {
if (service.equals(modelledResourceManager)) {
ModelledResourceManager modelledResourceManager
=
(ModelledResourceManager)findAlternateServiceFor(this.modelledResourceManager);
- if (resolver == null)
+ if (modelledResourceManager == null)
deactivate();
this.modelledResourceManager =
modelledResourceManager;
}
}
- else if (service instanceof IDirectoryFinder)
- finders.remove(service);
+ else if (service instanceof IDirectoryFinder)
+ finders.remove(service);
else
repositories.remove(service);
}
Modified:
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Location.java
URL:
http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Location.java?rev=1396873&r1=1396872&r2=1396873&view=diff
==============================================================================
---
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Location.java
(original)
+++
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Location.java
Thu Oct 11 00:19:39 2012
@@ -31,7 +31,7 @@ import org.osgi.framework.Version;
public class Location {
enum LocationType {
- SUBSYSTEM("subsystem", "subsystem"), IDIRFINDER(IDIR_SCHEME, IDIR_SCHEME),
URL("url", null);
+ SUBSYSTEM("subsystem", "subsystem"), IDIRFINDER(IDIR_SCHEME, IDIR_SCHEME),
URL("url", null), UNKNOWN("unknown", null);
final String toString;
final String scheme;
LocationType(String toString, String scheme) {this.toString = toString;
this.scheme = scheme;}
@@ -70,7 +70,10 @@ public class Location {
uri = locationUri;
}
} else {
- throw new IllegalArgumentException(location + " is not an absolute uri");
+ type = LocationType.UNKNOWN;
+ url = null;
+ uri = null;
+ subsystemUri = null;
}
}
@@ -96,6 +99,11 @@ public class Location {
return FileSystem.getFSRoot(new File(uri));
else
return FileSystem.getFSRoot(url.openStream());
+ case UNKNOWN:
+ // Only try to create a URL with the location value here. If the
+ // location was just a string and an InputStream was provided, this
+ // method will never be called.
+ return FileSystem.getFSRoot(new URL(value).openStream());
default : // should never get here as switch should cover all types
throw new UnsupportedOperationException("cannot open location of type
" + type);
}
Modified:
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResolverHook.java
URL:
http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResolverHook.java?rev=1396873&r1=1396872&r2=1396873&view=diff
==============================================================================
---
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResolverHook.java
(original)
+++
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResolverHook.java
Thu Oct 11 00:19:39 2012
@@ -30,6 +30,14 @@ import org.slf4j.LoggerFactory;
public class SubsystemResolverHook implements ResolverHook {
private static final Logger LOGGER =
LoggerFactory.getLogger(SubsystemResolverHook.class);
+ private final Subsystems subsystems;
+
+ public SubsystemResolverHook(Subsystems subsystems) {
+ if (subsystems == null)
+ throw new NullPointerException("Missing required
parameter: subsystems");
+ this.subsystems = subsystems;
+ }
+
public void end() {
// noop
}
@@ -39,7 +47,7 @@ public class SubsystemResolverHook imple
// there is at least one preferred provider.
// (1) Find the subsystem(s) containing
requirement.getResource() as a
// constituent.
- Collection<AriesSubsystem> requirers =
Activator.getInstance().getSubsystems().getSubsystemsReferencing(requirement.getResource());
+ Collection<AriesSubsystem> requirers =
subsystems.getSubsystemsReferencing(requirement.getResource());
// (2) For each candidate, ask each subsystem if the candidate
or any of
// the candidate's containing subsystems is a preferred
provider. If at
// least one preferred provider exists, filter out all other
candidates
@@ -62,7 +70,7 @@ public class SubsystemResolverHook imple
if
(revision.getSymbolicName().startsWith(Constants.RegionContextBundleSymbolicNamePrefix))
// Don't want to filter out the region
context bundle.
continue;
- Collection<AriesSubsystem> subsystems =
Activator.getInstance().getSubsystems().getSubsystemsReferencing(revision);
+ Collection<AriesSubsystem> subsystems =
this.subsystems.getSubsystemsReferencing(revision);
for (AriesSubsystem subsystem : subsystems) {
if (subsystem.isFeature()) {
// Feature subsystems require
no isolation.
@@ -87,7 +95,7 @@ public class SubsystemResolverHook imple
}
private boolean isResourceConstituentOfPreferredSubsystem(Resource
resource, AriesSubsystem preferer) {
- Collection<AriesSubsystem> subsystems =
Activator.getInstance().getSubsystems().getSubsystemsReferencing(resource);
+ Collection<AriesSubsystem> subsystems =
this.subsystems.getSubsystemsReferencing(resource);
for (AriesSubsystem subsystem : subsystems)
if
(preferer.getSubsystemManifest().getPreferredProviderHeader().contains(subsystem))
return true;
Modified:
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResolverHookFactory.java
URL:
http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResolverHookFactory.java?rev=1396873&r1=1396872&r2=1396873&view=diff
==============================================================================
---
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResolverHookFactory.java
(original)
+++
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResolverHookFactory.java
Thu Oct 11 00:19:39 2012
@@ -20,7 +20,14 @@ import org.osgi.framework.hooks.resolver
import org.osgi.framework.wiring.BundleRevision;
public class SubsystemResolverHookFactory implements ResolverHookFactory {
+ private final Subsystems subsystems;
+ public SubsystemResolverHookFactory(Subsystems subsystems) {
+ if (subsystems == null)
+ throw new NullPointerException("Missing required
parameter: subsystems");
+ this.subsystems = subsystems;
+ }
+
public ResolverHook begin(Collection<BundleRevision> triggers) {
- return new SubsystemResolverHook();
+ return new SubsystemResolverHook(subsystems);
}
}
Modified:
aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/RootSubsystemTest.java
URL:
http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/RootSubsystemTest.java?rev=1396873&r1=1396872&r2=1396873&view=diff
==============================================================================
---
aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/RootSubsystemTest.java
(original)
+++
aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/RootSubsystemTest.java
Thu Oct 11 00:19:39 2012
@@ -79,6 +79,11 @@ public class RootSubsystemTest extends S
public void testServiceEvents() throws Exception {
Subsystem root = getRootSubsystem();
Bundle core = getSubsystemCoreBundle();
+ // TODO Temporary(?) workaround to allow time for any tardy
service
+ // events to arrive so they can be cleared. So far, this sleep
has only
+ // been necessary on the IBM 6.0 64-bit JDK.
+ Thread.sleep(1000);
+ subsystemEvents.clear();
core.stop();
assertServiceEventsStop(root);
core.uninstall();