You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by pa...@apache.org on 2017/02/27 12:23:13 UTC
svn commit: r1784546 - in
/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core:
BaseUpdateInstallHelper.java UpdateHelper.java
Author: pauls
Date: Mon Feb 27 12:23:12 2017
New Revision: 1784546
URL: http://svn.apache.org/viewvc?rev=1784546&view=rev
Log:
Manually stop and start a bundle updated via the webconsole when a refresh is requested in order to avoid the bundle being stopped and started twice - during the update and in the refresh (FELIX-5566).
Modified:
felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BaseUpdateInstallHelper.java
felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/UpdateHelper.java
Modified: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BaseUpdateInstallHelper.java
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BaseUpdateInstallHelper.java?rev=1784546&r1=1784545&r2=1784546&view=diff
==============================================================================
--- felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BaseUpdateInstallHelper.java (original)
+++ felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BaseUpdateInstallHelper.java Mon Feb 27 12:23:12 2017
@@ -33,6 +33,7 @@ import org.osgi.framework.FrameworkEvent
import org.osgi.framework.FrameworkListener;
import org.osgi.service.log.LogService;
import org.osgi.service.packageadmin.PackageAdmin;
+import org.osgi.service.startlevel.StartLevel;
abstract class BaseUpdateInstallHelper implements Runnable
@@ -76,6 +77,11 @@ abstract class BaseUpdateInstallHelper i
{
return plugin;
}
+
+ protected Bundle getTargetBundle()
+ {
+ return null;
+ }
/**
@@ -119,13 +125,96 @@ abstract class BaseUpdateInstallHelper i
// invalid by the time we want to call the update
PackageAdmin pa = ( refreshPackages ) ? ( PackageAdmin ) getService( PackageAdmin.class.getName() ) : null;
- // perform the action!
- Bundle bundle = doRun();
-
- if ( pa != null && bundle != null )
+ // same for the startlevel
+ StartLevel startLevel = null;
+
+ Bundle bundle = getTargetBundle();
+
+ int state = pa != null && bundle != null ? bundle.getState() : 0;
+ int startFlags = 0;
+
+ // If the bundle has been started we want to stop it first, then update it, refresh it, and restart it
+ // because otherwise, it will be stopped and started twice (once by the update and once by the refresh)
+ if ((state & (Bundle.ACTIVE | Bundle.STARTING)) != 0)
+ {
+ // we need the StartLevel service before we stop the bundle
+ // before the update, since we might be stopping
+ // our selves in which case the bundle context will be
+ // invalid by the time we want to call the startlevel
+ startLevel = (StartLevel) getService(StartLevel.class.getName());
+
+ // We want to start the bundle afterwards without affecting the persistent state of the bundle
+ // However, we can only use the transient options if the framework startlevel is not less than the
+ // bundle startlevel (in case that there is no starlevel service we assume we are good).
+ if (startLevel == null || startLevel.getStartLevel() >= startLevel.getBundleStartLevel(bundle))
+ {
+ startFlags |= Bundle.START_TRANSIENT;
+ }
+
+ // If the bundle is in the starting state it might be lazy and not started yet - hence, start it
+ // according to its policy.
+ if (state == Bundle.STARTING)
+ {
+ startFlags |= Bundle.START_ACTIVATION_POLICY;
+ }
+
+ // We stop the bundle transiently - assuming we can also start it transiently later (see above) in which
+ // case we didn't mess with its persistent state at all.
+ bundle.stop(Bundle.STOP_TRANSIENT);
+ }
+
+ // We want to catch an exception during update to be able to restart the bundle if we stopped it previously
+ Exception rethrow = null;
+ try
+ {
+ // perform the action!
+ bundle = doRun();
+
+
+ if ( pa != null && bundle != null )
+ {
+ // refresh packages and give it at most 5 seconds to finish
+ refreshPackages( pa, plugin.getBundle().getBundleContext(), 5000L, bundle );
+ }
+ }
+ catch (Exception ex)
+ {
+ rethrow = ex;
+ throw ex;
+ }
+ finally
{
- // refresh packages and give it at most 5 seconds to finish
- refreshPackages( pa, plugin.getBundle().getBundleContext(), 5000L, bundle );
+ // If we stopped the bundle lets try to restart it (we created the correct flags above already).
+ if ((state & (Bundle.ACTIVE | Bundle.STARTING)) != 0)
+ {
+ try
+ {
+ bundle.start(startFlags);
+ }
+ catch (Exception ex)
+ {
+ if (rethrow == null)
+ {
+ throw ex;
+ }
+ else
+ {
+ try
+ {
+ getLog().log( LogService.LOG_ERROR, "Cannot restart bundle: " + bundle + " after exception during update!", ex);
+ }
+ catch ( Exception secondary )
+ {
+ // at the time this exception happens the log used might have
+ // been destroyed and is not available to use any longer. So
+ // we only can write to stderr at this time to at least get
+ // some message out ...
+ System.err.println( "Cannot restart bundle: " + bundle + " after exception during update!");
+ ex.printStackTrace( System.err );
+ }
+ }
+ }
+ }
}
}
catch ( Exception e )
Modified: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/UpdateHelper.java
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/UpdateHelper.java?rev=1784546&r1=1784545&r2=1784546&view=diff
==============================================================================
--- felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/UpdateHelper.java (original)
+++ felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/UpdateHelper.java Mon Feb 27 12:23:12 2017
@@ -61,6 +61,10 @@ class UpdateHelper extends BaseUpdateIns
return bundle;
}
+ protected Bundle getTargetBundle()
+ {
+ return bundle;
+ }
protected Bundle doRun() throws Exception
{
@@ -98,7 +102,6 @@ class UpdateHelper extends BaseUpdateIns
return null;
}
-
private boolean updateFromBundleLocation()
{
getLog().log( LogService.LOG_DEBUG, "Trying to update with Bundle.update()" );