You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ri...@apache.org on 2009/06/10 23:15:12 UTC
svn commit: r783522 - in
/felix/trunk/framework/src/main/java/org/apache/felix/framework:
BundleImpl.java Felix.java ModuleImpl.java StartLevelImpl.java
util/EventDispatcher.java
Author: rickhall
Date: Wed Jun 10 21:15:12 2009
New Revision: 783522
URL: http://svn.apache.org/viewvc?rev=783522&view=rev
Log:
More modifications for activation policies. (FELIX-749)
Modified:
felix/trunk/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java
felix/trunk/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java
felix/trunk/framework/src/main/java/org/apache/felix/framework/StartLevelImpl.java
felix/trunk/framework/src/main/java/org/apache/felix/framework/util/EventDispatcher.java
Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/BundleImpl.java?rev=783522&r1=783521&r2=783522&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/BundleImpl.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/BundleImpl.java Wed Jun 10 21:15:12 2009
@@ -38,7 +38,7 @@
private final BundleArchive m_archive;
private IModule[] m_modules = new IModule[0];
private volatile int m_state;
- private int m_runtimeActivationPolicy;
+ private boolean m_useDeclaredActivationPolicy;
private BundleActivator m_activator = null;
private BundleContext m_context = null;
private final Map m_cachedHeaders = new HashMap();
@@ -63,7 +63,7 @@
__m_felix = null;
m_archive = null;
m_state = Bundle.INSTALLED;
- m_runtimeActivationPolicy = 0;
+ m_useDeclaredActivationPolicy = false;
m_stale = false;
m_activator = null;
m_context = null;
@@ -74,7 +74,7 @@
__m_felix = felix;
m_archive = archive;
m_state = Bundle.INSTALLED;
- m_runtimeActivationPolicy = 0;
+ m_useDeclaredActivationPolicy = false;
m_stale = false;
m_activator = null;
m_context = null;
@@ -131,16 +131,14 @@
}
}
- synchronized int getRuntimeActivationPolicy()
+ synchronized boolean isDeclaredActivationPolicyUsed()
{
- return (m_runtimeActivationPolicy == IModule.EAGER_ACTIVATION)
- ? IModule.EAGER_ACTIVATION
- : getCurrentModule().getDeclaredActivationPolicy();
+ return m_useDeclaredActivationPolicy;
}
- synchronized void setRuntimeActivationPolicy(int policy)
+ synchronized void setDeclaredActivationPolicyUsed(boolean b)
{
- m_runtimeActivationPolicy = policy;
+ m_useDeclaredActivationPolicy = b;
}
synchronized BundleActivator getActivator()
Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java?rev=783522&r1=783521&r2=783522&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java Wed Jun 10 21:15:12 2009
@@ -1004,8 +1004,9 @@
}
}
// Stop the bundle if necessary.
- else if ((impl.getState() == Bundle.ACTIVE) &&
- (impl.getStartLevel(getInitialBundleStartLevel())
+ else if (((impl.getState() == Bundle.ACTIVE)
+ || (impl.getState() == Bundle.STARTING))
+ && (impl.getStartLevel(getInitialBundleStartLevel())
> getActiveStartLevel()))
{
try
@@ -1145,7 +1146,6 @@
try
{
// Start the bundle if necessary.
- // Start the bundle if necessary.
if (((impl.getPersistentState() == Bundle.ACTIVE)
|| (impl.getPersistentState() == Bundle.STARTING))
&& (impl.getStartLevel(getInitialBundleStartLevel())
@@ -1159,8 +1159,9 @@
startBundle(impl, options);
}
// Stop the bundle if necessary.
- else if ((impl.getState() == Bundle.ACTIVE) &&
- (impl.getStartLevel(getInitialBundleStartLevel())
+ else if (((impl.getState() == Bundle.ACTIVE)
+ || (impl.getState() == Bundle.STARTING))
+ && (impl.getStartLevel(getInitialBundleStartLevel())
> getActiveStartLevel()))
{
stopBundle(impl, false);
@@ -1209,6 +1210,25 @@
|| (((BundleImpl) bundle).getPersistentState() == Bundle.STARTING);
}
+ /**
+ * Returns whether the bundle is using its declared activation policy;
+ * this is an method implementation for the Start Level service.
+ * @param bundle The bundle to examine.
+ * @return <tt>true</tt> if the bundle is using its declared activation
+ * policy, <tt>false</tt> otherwise.
+ * @throws java.lang.IllegalArgumentException If the specified
+ * bundle has been uninstalled.
+ **/
+ boolean isBundleActivationPolicyUsed(Bundle bundle)
+ {
+ if (bundle.getState() == Bundle.UNINSTALLED)
+ {
+ throw new IllegalArgumentException("Bundle is uninstalled.");
+ }
+
+ return ((BundleImpl) bundle).isDeclaredActivationPolicyUsed();
+ }
+
//
// Implementation of Bundle interface methods.
//
@@ -1386,6 +1406,8 @@
// that case, the global lock will be acquired to make sure no
// bundles can be installed or uninstalled during the resolve.
+ int eventType;
+
// Acquire bundle lock.
try
{
@@ -1405,11 +1427,9 @@
}
}
- // Set the bundl
- bundle.setRuntimeActivationPolicy(
- ((options & Bundle.START_ACTIVATION_POLICY) > 0)
- ? IModule.LAZY_ACTIVATION
- : IModule.EAGER_ACTIVATION);
+ // Record whether the bundle is using its declared activation policy.
+ bundle.setDeclaredActivationPolicyUsed(
+ (options & Bundle.START_ACTIVATION_POLICY) != 0);
try
{
@@ -1473,25 +1493,35 @@
resolveBundle(bundle);
// No break.
case Bundle.RESOLVED:
- setBundleStateAndNotify(bundle, Bundle.STARTING);
- fireBundleEvent(BundleEvent.STARTING, bundle);
break;
}
// Set the bundle's context.
bundle.setBundleContext(new BundleContextImpl(m_logger, this, bundle));
+ // At this point, no matter if the bundle's activation policy is
+ // eager or deferred, we need to set the bundle's state to STARTING.
+ // We don't fire a BundleEvent here for this state change, since
+ // STARTING events are only fired if we are invoking the activator,
+ // which we may not do if activation is deferred.
+ setBundleStateAndNotify(bundle, Bundle.STARTING);
+
// If the bundle's activation policy is eager or activation has already
// been triggered, then activate the bundle immediately.
- if ((bundle.getRuntimeActivationPolicy() != IModule.LAZY_ACTIVATION)
+ if (!bundle.isDeclaredActivationPolicyUsed()
+ || (bundle.getCurrentModule().getDeclaredActivationPolicy() != IModule.LAZY_ACTIVATION)
|| ((ModuleImpl) bundle.getCurrentModule()).isActivationTrigger())
{
- activateBundle(bundle);
+ // Record the event type for the final event and activate.
+ eventType = BundleEvent.STARTED;
+ // Note that the STARTING event is thrown in the activateBundle() method.
+ activateBundle(bundle, false);
}
// Otherwise, defer bundle activation.
else
{
- setBundleStateAndNotify(bundle, Bundle.STARTING);
+ // Record the event type for the final event.
+ eventType = BundleEvent.LAZY_ACTIVATION;
}
// We still need to fire the STARTED event, but we will do
@@ -1503,13 +1533,12 @@
releaseBundleLock(bundle);
}
- // If there was no exception, then we should fire the STARTED event
- // here without holding the lock.
-// TODO: LAZY - WE SHOULD REALLY BE FIRING EVENT HERE, OUTSIDE OF LOCK.
-// fireBundleEvent(BundleEvent.STARTED, bundle);
+ // If there was no exception, then we should fire the STARTED
+ // or LAZY_ACTIVATION event here without holding the lock.
+ fireBundleEvent(eventType, bundle);
}
- public void activateBundle(BundleImpl bundle) throws BundleException
+ void activateBundle(BundleImpl bundle, boolean fireEvent) throws BundleException
{
// CONCURRENCY NOTE:
// We will first acquire the bundle lock for the specific bundle
@@ -1538,6 +1567,9 @@
return;
}
+ // Fire STARTING event to signify call to bundle activator.
+ fireBundleEvent(BundleEvent.STARTING, bundle);
+
try
{
// Set the bundle's activator.
@@ -1603,10 +1635,15 @@
releaseBundleLock(bundle);
}
- // If there was no exception, then we should fire the STARTED event
- // here without holding the lock.
-// TODO: LAZY - WE COULD BE HOLDING THE LOCK FROM startBundle() ABOVE.
- fireBundleEvent(BundleEvent.STARTED, bundle);
+ // If there was no exception, then we should fire the STARTED
+ // event here without holding the lock if specified.
+ // TODO: LAZY - It would be nice to figure out how to do this without
+ // duplicating code; this method is called from two different
+ // places -- one fires the event itself the other one needs it.
+ if (fireEvent)
+ {
+ fireBundleEvent(BundleEvent.STARTED, bundle);
+ }
}
void updateBundle(BundleImpl bundle, InputStream is)
@@ -1876,6 +1913,15 @@
bundle.setPersistentStateInactive();
}
+ // If the bundle is not persistently started, then we
+ // need to reset the activation policy flag, since it
+ // does not persist across persistent stops or transient
+ // stops.
+ if (!isBundlePersistentlyStarted(bundle))
+ {
+ bundle.setDeclaredActivationPolicyUsed(false);
+ }
+
// As per the OSGi spec, fragment bundles can not be stopped and must
// throw a BundleException when there is an attempt to stop one.
if (Util.isFragment(bundle.getCurrentModule()))
@@ -1883,12 +1929,14 @@
throw new BundleException("Fragment bundles can not be stopped: " + bundle);
}
+ boolean wasActive = false;
switch (bundle.getState())
{
case Bundle.UNINSTALLED:
throw new IllegalStateException("Cannot stop an uninstalled bundle.");
case Bundle.STARTING:
- if (bundle.getRuntimeActivationPolicy() != IModule.LAZY_ACTIVATION)
+ if (bundle.isDeclaredActivationPolicyUsed()
+ && bundle.getCurrentModule().getDeclaredActivationPolicy() != IModule.LAZY_ACTIVATION)
{
throw new BundleException(
"Stopping a starting or stopping bundle is currently not supported.");
@@ -1901,13 +1949,18 @@
case Bundle.RESOLVED:
return;
case Bundle.ACTIVE:
- // Set bundle state..
- setBundleStateAndNotify(bundle, Bundle.STOPPING);
- fireBundleEvent(BundleEvent.STOPPING, bundle);
+ wasActive = true;
break;
}
- if (bundle.getState() != Bundle.STARTING)
+ // At this point, no matter if the bundle's activation policy is
+ // eager or deferred, we need to set the bundle's state to STOPPING
+ // and fire the STOPPING event.
+ setBundleStateAndNotify(bundle, Bundle.STOPPING);
+ fireBundleEvent(BundleEvent.STOPPING, bundle);
+
+ // If the bundle was active, then invoke the activator stop() method.
+ if (wasActive)
{
try
{
Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java?rev=783522&r1=783521&r2=783522&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java Wed Jun 10 21:15:12 2009
@@ -1549,7 +1549,10 @@
if (clazz == null)
{
- int activationPolicy = ((BundleImpl) getBundle()).getRuntimeActivationPolicy();
+ int activationPolicy =
+ ((BundleImpl) getBundle()).isDeclaredActivationPolicyUsed()
+ ? ((BundleImpl) getBundle()).getCurrentModule().getDeclaredActivationPolicy()
+ : IModule.EAGER_ACTIVATION;
// If the module is using deferred activation, then if
// we load this class from this module we need to activate
@@ -1645,7 +1648,7 @@
try
{
((BundleImpl) ((Object[]) deferredList.get(i))[1]).getFramework().activateBundle(
- (BundleImpl) ((Object[]) deferredList.get(i))[1]);
+ (BundleImpl) ((Object[]) deferredList.get(i))[1], true);
}
catch (BundleException ex)
{
Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/StartLevelImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/StartLevelImpl.java?rev=783522&r1=783521&r2=783522&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/StartLevelImpl.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/StartLevelImpl.java Wed Jun 10 21:15:12 2009
@@ -215,7 +215,7 @@
**/
public boolean isBundleActivationPolicyUsed(Bundle bundle)
{
- throw new UnsupportedOperationException("This feature has not yet been implemented.");
+ return m_felix.isBundleActivationPolicyUsed(bundle);
}
public void run()
Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/util/EventDispatcher.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/util/EventDispatcher.java?rev=783522&r1=783521&r2=783522&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/util/EventDispatcher.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/util/EventDispatcher.java Wed Jun 10 21:15:12 2009
@@ -595,13 +595,15 @@
syncListeners = m_syncBundleListeners;
}
+System.out.println("+++ FIRING BUNDLE EVENT " + event.getType() + " FROM " + event.getBundle().getSymbolicName());
// Fire synchronous bundle listeners immediately on the calling thread.
fireEventImmediately(m_logger, Request.BUNDLE_EVENT, syncListeners, event);
// The spec says that asynchronous bundle listeners do not get events
- // of types STARTING or STOPPING.
+ // of types STARTING, STOPPING, or LAZY_ACTIVATION.
if ((event.getType() != BundleEvent.STARTING) &&
- (event.getType() != BundleEvent.STOPPING))
+ (event.getType() != BundleEvent.STOPPING) &&
+ (event.getType() != BundleEvent.LAZY_ACTIVATION))
{
// Fire asynchronous bundle listeners on a separate thread.
fireEventAsynchronously(m_logger, Request.BUNDLE_EVENT, listeners, event);