FELIX-3345 Apply patch FELIX-3345-2.diff by David Jencks (thanks alot) slightly reformatted and turned around checks (assuming the positive success of failure)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1298266 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/Activator.java b/scr/src/main/java/org/apache/felix/scr/impl/Activator.java
index 267f7dc..aa2c2b2 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/Activator.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/Activator.java
@@ -352,15 +352,22 @@
if ( activators[i] instanceof BundleComponentActivator )
{
final BundleComponentActivator ga = ( BundleComponentActivator ) activators[i];
- final Bundle bundle = ga.getBundleContext().getBundle();
try
{
- ga.dispose( ComponentConstants.DEACTIVATION_REASON_DISPOSED );
+ final Bundle bundle = ga.getBundleContext().getBundle();
+ try
+ {
+ ga.dispose( ComponentConstants.DEACTIVATION_REASON_DISPOSED );
+ }
+ catch ( Exception e )
+ {
+ log( LogService.LOG_ERROR, m_context.getBundle(), "Error while disposing components of bundle "
+ + bundle.getSymbolicName() + "/" + bundle.getBundleId(), e );
+ }
}
- catch ( Exception e )
+ catch ( IllegalStateException e )
{
- log( LogService.LOG_ERROR, m_context.getBundle(), "Error while disposing components of bundle "
- + bundle.getSymbolicName() + "/" + bundle.getBundleId(), e );
+ //bundle context was already shut down in another thread, bundle is not available.
}
}
}
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java b/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java
index 86b9d9d..e3da405 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/BundleComponentActivator.java
@@ -465,7 +465,7 @@
/**
- * Returns an array of {@link ComponentManager} instances which match the
+ * Returns an array of {@link ComponentHolder} instances which match the
* <code>name</code>. If the <code>name</code> is <code>null</code> an
* array of all currently known component managers is returned. Otherwise
* an array containing a single component manager matching the name is
@@ -611,14 +611,23 @@
message = "[" + metadata.getName() + "] " + message;
}
- Object logger = m_logService.getService();
- if ( logger == null )
+ ServiceTracker logService = m_logService;
+ if ( logService != null )
{
- Activator.log( level, getBundleContext().getBundle(), message, ex );
+ Object logger = logService.getService();
+ if ( logger == null )
+ {
+ Activator.log( level, getBundleContext().getBundle(), message, ex );
+ }
+ else
+ {
+ ( ( LogService ) logger ).log( level, message, ex );
+ }
}
else
{
- ( ( LogService ) logger ).log( level, message, ex );
+ // BCA has been disposed off, bundle context is probably invalid. Try to log something.
+ Activator.log( level, null, message, ex );
}
}
}
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurationSupport.java b/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurationSupport.java
index 7a1e137..3612d3e 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurationSupport.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/config/ConfigurationSupport.java
@@ -109,7 +109,14 @@
}
finally
{
- bundleContext.ungetService(caRef);
+ try
+ {
+ bundleContext.ungetService( caRef );
+ }
+ catch ( IllegalStateException e )
+ {
+ // ignore, bundle context was shut down during the above.
+ }
}
}
}
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
index f386cfa..3068384 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
@@ -73,22 +73,22 @@
private int m_size;
// the object on which the bind/undind methods are to be called
- private transient Object m_componentInstance;
+ private volatile Object m_componentInstance;
// the bind method
- private BindMethod m_bind;
+ private volatile BindMethod m_bind;
// the updated method
- private UpdatedMethod m_updated;
+ private volatile UpdatedMethod m_updated;
// the unbind method
- private UnbindMethod m_unbind;
+ private volatile UnbindMethod m_unbind;
// the target service filter string
- private String m_target;
+ private volatile String m_target;
// the target service filter
- private Filter m_targetFilter;
+ private volatile Filter m_targetFilter;
/**
@@ -121,23 +121,23 @@
/**
* Initialize binding methods.
*/
- private void initBindingMethods()
+ private void initBindingMethods(Class instanceClass)
{
m_bind = new BindMethod( m_componentManager,
m_dependencyMetadata.getBind(),
- m_componentInstance.getClass(),
+ instanceClass,
m_dependencyMetadata.getName(),
m_dependencyMetadata.getInterface()
);
m_updated = new UpdatedMethod( m_componentManager,
m_dependencyMetadata.getUpdated(),
- m_componentInstance.getClass(),
+ instanceClass,
m_dependencyMetadata.getName(),
m_dependencyMetadata.getInterface()
);
m_unbind = new UnbindMethod( m_componentManager,
m_dependencyMetadata.getUnbind(),
- m_componentInstance.getClass(),
+ instanceClass,
m_dependencyMetadata.getName(),
m_dependencyMetadata.getInterface()
);
@@ -816,7 +816,18 @@
Object service = m_bound.remove( serviceReference );
if ( service != null && service != BOUND_SERVICE_SENTINEL )
{
- m_componentManager.getActivator().getBundleContext().ungetService( serviceReference );
+ try
+ {
+ m_componentManager.getActivator().getBundleContext().ungetService( serviceReference );
+ }
+ catch ( IllegalStateException e )
+ {
+ m_componentManager.log( LogService.LOG_INFO,
+ "For dependency {0}, trying to unget ServiceReference {1} on invalid bundle context {2}",
+ new Object[]
+ { m_dependencyMetadata.getName(), serviceReference.getProperty( Constants.SERVICE_ID ),
+ serviceReference }, null );
+ }
}
}
@@ -863,8 +874,8 @@
boolean open( Object instance )
{
+ initBindingMethods( instance.getClass() );
m_componentInstance = instance;
- initBindingMethods();
return bind();
}
@@ -1025,20 +1036,30 @@
// null. This is valid for both immediate and delayed components
if( m_componentInstance != null )
{
- return m_bind.invoke( m_componentInstance, new BindMethod.Service()
+ if ( m_bind != null )
{
- public ServiceReference getReference()
+ return m_bind.invoke( m_componentInstance, new BindMethod.Service()
{
- bindService( ref );
- return ref;
- }
+ public ServiceReference getReference()
+ {
+ bindService( ref );
+ return ref;
+ }
- public Object getInstance()
- {
- return getService( ref );
- }
- }, true );
+ public Object getInstance()
+ {
+ return getService( ref );
+ }
+ }, true );
+ }
+
+ // Concurrency Issue: The component instance still exists but
+ // but the defined bind method field is null, fail binding
+ m_componentManager.log( LogService.LOG_INFO,
+ "DependencyManager : Component instance present, but DependencyManager shut down (no bind method)",
+ null );
+ return false;
}
else if ( !m_componentManager.getComponentMetadata().isImmediate() )
{