FELIX-3456 use Registered status to create component if missing
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1371287 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/helper/BaseMethod.java b/scr/src/main/java/org/apache/felix/scr/impl/helper/BaseMethod.java
index cc2c912..622ee32 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/helper/BaseMethod.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/helper/BaseMethod.java
@@ -184,8 +184,8 @@
{
// log and return null
getComponentManager().log( LogService.LOG_ERROR,
- "findMethod: Suitable but non-accessible method found in class {0}", new Object[]
- { targetClass.getName() }, null );
+ "findMethod: Suitable but non-accessible method {0} found in class {1}, subclass of {2}", new Object[]
+ { getMethodName(), theClass.getName(), targetClass.getName() }, null );
break;
}
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/helper/BindMethod.java b/scr/src/main/java/org/apache/felix/scr/impl/helper/BindMethod.java
index a542ba3..4d22578 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/helper/BindMethod.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/helper/BindMethod.java
@@ -38,15 +38,13 @@
private static final Class OBJECT_CLASS = Object.class;
- private final String m_referenceName;
private final String m_referenceClassName;
public BindMethod( final AbstractComponentManager componentManager, final String methodName,
- final Class componentClass, final String referenceName, final String referenceClassName )
+ final Class componentClass, final String referenceClassName )
{
super( componentManager, methodName, componentClass );
- m_referenceName = referenceName;
m_referenceClassName = referenceClassName;
}
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/helper/UnbindMethod.java b/scr/src/main/java/org/apache/felix/scr/impl/helper/UnbindMethod.java
index 4c4150b..b0db1e4 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/helper/UnbindMethod.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/helper/UnbindMethod.java
@@ -31,7 +31,7 @@
public UnbindMethod( final AbstractComponentManager componentManager, final String methodName,
final Class componentClass, final String referenceName, final String referenceClassName )
{
- super( componentManager, methodName, componentClass, referenceName, referenceClassName );
+ super( componentManager, methodName, componentClass, referenceClassName );
}
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/helper/UpdatedMethod.java b/scr/src/main/java/org/apache/felix/scr/impl/helper/UpdatedMethod.java
index 2283888..2f68714 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/helper/UpdatedMethod.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/helper/UpdatedMethod.java
@@ -31,7 +31,7 @@
public UpdatedMethod( final AbstractComponentManager componentManager, final String methodName,
final Class componentClass, final String referenceName, final String referenceClassName )
{
- super( componentManager, methodName, componentClass, referenceName, referenceClassName );
+ super( componentManager, methodName, componentClass, referenceClassName );
}
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
index a1c3d02..97b5265 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
@@ -31,6 +31,7 @@
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReentrantReadWriteLock;
+import EDU.oswego.cs.dl.util.concurrent.ReaderPreferenceReadWriteLock;
import org.apache.felix.scr.Component;
import org.apache.felix.scr.Reference;
import org.apache.felix.scr.impl.BundleComponentActivator;
@@ -90,7 +91,7 @@
private BundleComponentActivator m_activator;
// The ServiceRegistration
- private final AtomicReferenceWrapper m_serviceRegistration = new AtomicReferenceWrapper( );
+ private final AtomicReferenceWrapper m_serviceRegistration;
private final LockWrapper m_stateLock;
@@ -114,10 +115,12 @@
if (JUC_AVAILABLE)
{
m_stateLock = new JLock();
+ m_serviceRegistration = new JAtomicReferenceWrapper();
}
else
{
m_stateLock = new EDULock();
+ m_serviceRegistration = new EDUAtomicReferenceWrapper();
}
// dump component details
@@ -151,17 +154,15 @@
//ImmediateComponentHolder should be in this manager package and this should be default access.
public final boolean obtainReadLock()
{
-// new Exception("Stack trace obtainReadLock").printStackTrace();
if (m_stateLock.getReadHoldCount() >0)
{
return false;
-// throw new IllegalStateException( "nested read locks" );
}
try
{
if (!m_stateLock.tryReadLock( m_timeout ) )
{
- throw new IllegalStateException( "Could not obtain lock" );
+ throw new IllegalStateException( "Could not obtain lock in " + m_timeout + " milliseconds for component " + m_componentMetadata.getName() );
}
}
catch ( InterruptedException e )
@@ -175,13 +176,11 @@
public final void releaseReadLock()
{
-// new Exception("Stack trace releaseReadLock").printStackTrace();
m_stateLock.unlockReadLock();
}
- public final void escalateLock()
+ final void escalateLock()
{
-// new Exception("Stack trace escalateLock").printStackTrace();
m_stateLock.unlockReadLock();
try
{
@@ -197,13 +196,12 @@
}
}
- public final void deescalateLock()
+ final void deescalateLock()
{
-// new Exception("Stack trace deescalateLock").printStackTrace();
m_stateLock.deescalate();
}
- public final void checkLocked()
+ final void checkLocked()
{
if ( m_stateLock.getReadHoldCount() == 0 && m_stateLock.getWriteHoldCount() == 0 )
{
@@ -211,7 +209,7 @@
}
}
- public final boolean isWriteLocked()
+ final boolean isWriteLocked()
{
return m_stateLock.getWriteHoldCount() > 0;
}
@@ -924,7 +922,7 @@
*/
public Dictionary getServiceProperties()
{
- return copyTo( null, getProperties(), false);
+ return copyTo( null, getProperties(), false );
}
/**
@@ -1304,6 +1302,10 @@
acm.escalateLock();
try
{
+ if ( acm.isImmediate() )
+ {
+ acm.changeState( Active.getInstance() );
+ }
if ( !acm.createComponent() )
{
// component creation failed, not active now
@@ -1629,45 +1631,62 @@
}
}
- private static class EDULock implements LockWrapper
+ private static class EDULock extends EDU.oswego.cs.dl.util.concurrent.ReentrantWriterPreferenceReadWriteLock implements LockWrapper
{
- private final EDU.oswego.cs.dl.util.concurrent.ReentrantLock lock = new EDU.oswego.cs.dl.util.concurrent.ReentrantLock();
-
public boolean tryReadLock( long milliseconds ) throws InterruptedException
{
- return lock.attempt( milliseconds );
+ return readLock().attempt( milliseconds );
}
public long getReadHoldCount()
{
- return lock.holds();
+ return readers_.size();
}
public void unlockReadLock()
{
- lock.release();
+ readLock().release();
}
public boolean tryWriteLock( long milliseconds ) throws InterruptedException
{
- return false;
+ return writeLock().attempt( milliseconds );
}
public long getWriteHoldCount()
{
- return 0;
+ return writeHolds_;
}
public void unlockWriteLock()
{
+ writeLock().release();
}
public void deescalate()
{
+ try
+ {
+ readLock().acquire();
+ }
+ catch ( InterruptedException e )
+ {
+ //should not happen, we have the write lock
+ throw ( IllegalStateException ) new IllegalStateException( "Unexpected InterruptedException while acquiring read lock and holding write lock" ).initCause( e );
+ }
+ writeLock().release();
}
}
- static class AtomicReferenceWrapper
+ private interface AtomicReferenceWrapper
+ {
+ ServiceRegistration get();
+
+ boolean compareAndSet(ServiceRegistration expected, ServiceRegistration replacement);
+
+ }
+
+ private static class JAtomicReferenceWrapper implements AtomicReferenceWrapper
{
private final AtomicReference ref = new AtomicReference( );
@@ -1681,4 +1700,20 @@
return ref.compareAndSet( expected, replacement );
}
}
+
+ private static class EDUAtomicReferenceWrapper implements AtomicReferenceWrapper
+ {
+ private final EDU.oswego.cs.dl.util.concurrent.SynchronizedRef ref = new EDU.oswego.cs.dl.util.concurrent.SynchronizedRef( null );
+
+ public ServiceRegistration get()
+ {
+ return ( ServiceRegistration ) ref.get();
+ }
+
+ public boolean compareAndSet(ServiceRegistration expected, ServiceRegistration replacement)
+ {
+ return ref.commit( expected, replacement );
+ }
+ }
+
}
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/ConfigurationComponentFactoryImpl.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/ConfigurationComponentFactoryImpl.java
index e698544..a6ac519 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/ConfigurationComponentFactoryImpl.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/ConfigurationComponentFactoryImpl.java
@@ -258,5 +258,9 @@
super( activator, componentHolder, metadata );
}
+ public boolean isImmediate()
+ {
+ return true;
+ }
}
}
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/DelayedComponentManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/DelayedComponentManager.java
index b203505..1c94b8e 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/DelayedComponentManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/DelayedComponentManager.java
@@ -32,10 +32,6 @@
public class DelayedComponentManager extends ImmediateComponentManager
{
-// // keep the using bundles as reference "counters" for instance deactivation
-// private int m_useCount;
-
-
/**
* @param activator
* @param metadata
@@ -44,65 +40,12 @@
ComponentMetadata metadata )
{
super( activator, componentHolder, metadata );
-// this.m_useCount = 0;
}
-// protected void deleteComponent( int reason )
+
+// State getSatisfiedState()
// {
-// // only have to delete, if there is actually an instance
-// if ( getInstance() != null )
-// {
-// super.deleteComponent( reason );
-// }
-//
-// // ensure the refence set is also clear
-//// m_useCount = 0;
+// return Registered.getInstance();
// }
- State getSatisfiedState()
- {
- return Registered.getInstance();
- }
-
- //---------- ServiceFactory interface -------------------------------------
-
-// public Object getService( Bundle bundle, ServiceRegistration sr )
-// {
-// obtainReadLock();
-// try
-// {
-// m_useCount++;
-// return state().getService( this );
-// }
-// finally
-// {
-// releaseReadLock();
-// }
-// }
-//
-// public void ungetService( Bundle bundle, ServiceRegistration sr, Object service )
-// {
-// obtainReadLock();
-// try
-// {
-// // the framework should not call ungetService more than it calls
-// // calls getService. Still, we want to be sure to not go below zero
-// if ( m_useCount > 0 )
-// {
-// m_useCount--;
-//
-// // unget the service instance if no bundle is using it
-// // any longer unless delayed component instances have to
-// // be kept (FELIX-3039)
-// if ( m_useCount == 0 && !getActivator().getConfiguration().keepInstances() )
-// {
-// state().ungetService( this );
-// }
-// }
-// }
-// finally
-// {
-// releaseReadLock();
-// }
-// }
}
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 578ff1c..c292180 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
@@ -125,8 +125,7 @@
m_bind = new BindMethod( m_componentManager,
m_dependencyMetadata.getBind(),
instanceClass,
- m_dependencyMetadata.getName(),
- m_dependencyMetadata.getInterface()
+ m_dependencyMetadata.getInterface()
);
m_updated = new UpdatedMethod( m_componentManager,
m_dependencyMetadata.getUpdated(),
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
index 5e5b0f3..875749a 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
@@ -150,6 +150,7 @@
if ( m_implementationObject != null )
{
disposeImplementationObject( m_implementationObject, m_componentContext, reason );
+ m_useCount = 0;
m_implementationObject = null;
m_componentContext = null;
m_properties = null;
@@ -310,7 +311,7 @@
State getSatisfiedState()
{
- return Active.getInstance();
+ return Registered.getInstance();
}
protected void setFactoryProperties( Dictionary dictionary )
@@ -627,8 +628,13 @@
{
if ( m_useCount == 0 )
{
- m_useCount++;
- return state().getService( this );
+ //state should be "Registered"
+ Object result = state().getService( this );
+ if ( result != null )
+ {
+ m_useCount++;
+ }
+ return result;
}
}
finally
diff --git a/scr/src/test/java/org/apache/felix/scr/impl/helper/BindMethodTest.java b/scr/src/test/java/org/apache/felix/scr/impl/helper/BindMethodTest.java
index 4ad5c3f..595f61c 100644
--- a/scr/src/test/java/org/apache/felix/scr/impl/helper/BindMethodTest.java
+++ b/scr/src/test/java/org/apache/felix/scr/impl/helper/BindMethodTest.java
@@ -439,8 +439,8 @@
}
};
ImmediateComponentManager icm = new ImmediateComponentManager( null, null, metadata );
- BindMethod bm = new BindMethod( icm, methodName, component.getClass(), "reference",
- FakeService.class.getName() );
+ BindMethod bm = new BindMethod( icm, methodName, component.getClass(),
+ FakeService.class.getName() );
bm.invoke( component, m_service, null );
assertEquals( expectCallPerformed, component.callPerformed );
}