FELIX-658 Optionally skip stopping unaffected bundles when updating a deployment package
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@682377 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/deploymentadmin/service/pom.xml b/deploymentadmin/service/pom.xml
index 8988720..1869d09 100644
--- a/deploymentadmin/service/pom.xml
+++ b/deploymentadmin/service/pom.xml
@@ -33,14 +33,13 @@
<dependency>
<groupId>${pom.groupId}</groupId>
<artifactId>org.osgi.core</artifactId>
- <version>1.1.0-SNAPSHOT</version>
+ <version>1.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>${pom.groupId}</groupId>
<artifactId>org.osgi.compendium</artifactId>
<version>1.1.0-SNAPSHOT</version>
- <scope>provided</scope>
</dependency>
<dependency>
<groupId>${pom.groupId}</groupId>
@@ -63,8 +62,8 @@
<Bundle-Name>Apache Felix Deployment Admin</Bundle-Name>
<Bundle-Description>A bundle that implements the Deployment Admin.</Bundle-Description>
<Bundle-Vendor>The Apache Software Foundation</Bundle-Vendor>
- <Private-Package>org.apache.felix.deploymentadmin.spi</Private-Package>
- <Export-Package>org.apache.felix.deploymentadmin,org.osgi.service.deploymentadmin.*;version="1.0.0"</Export-Package>
+ <Private-Package>org.apache.felix.deploymentadmin.*</Private-Package>
+ <Export-Package>org.osgi.service.deploymentadmin.*;version="1.0"</Export-Package>
</instructions>
</configuration>
</plugin>
diff --git a/deploymentadmin/service/src/main/java/org/apache/felix/deploymentadmin/spi/StopBundleCommand.java b/deploymentadmin/service/src/main/java/org/apache/felix/deploymentadmin/spi/StopBundleCommand.java
index ee56373..8500f75 100644
--- a/deploymentadmin/service/src/main/java/org/apache/felix/deploymentadmin/spi/StopBundleCommand.java
+++ b/deploymentadmin/service/src/main/java/org/apache/felix/deploymentadmin/spi/StopBundleCommand.java
@@ -19,6 +19,7 @@
package org.apache.felix.deploymentadmin.spi;
import org.apache.felix.deploymentadmin.AbstractDeploymentPackage;
+import org.apache.felix.deploymentadmin.BundleInfoImpl;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;
import org.osgi.service.deploymentadmin.BundleInfo;
@@ -27,6 +28,12 @@
/**
* Command that stops all bundles described in the target deployment package of a deployment session.
+ *
+ * By spec every single bundle of the target package should be stopped, even if this is not strictly necessary
+ * because of bundles being unaffected by an update. To be able to skip the stopping of unaffected bundles the
+ * following system property can be defined: <code>org.apache.felix.deploymentadmin.stopunaffectedbundle</code>.
+ * If this property has value <code>false</code> (case insensitive) then unaffected bundles will not be stopped,
+ * in all other cases the bundles will be stopped according to the OSGi specification.
*/
public class StopBundleCommand extends Command {
@@ -37,8 +44,13 @@
if (isCancelled()) {
throw new DeploymentException(DeploymentException.CODE_CANCELLED);
}
- Bundle bundle = target.getBundle(bundleInfos[i].getSymbolicName());
+ String symbolicName = bundleInfos[i].getSymbolicName();
+ Bundle bundle = target.getBundle(symbolicName);
if (bundle != null) {
+ String stopUnaffectedBundle = System.getProperty("org.apache.felix.deploymentadmin.stopunaffectedbundle", "true");
+ if (stopUnaffectedBundle.equalsIgnoreCase("false") && omitBundleStop(session, symbolicName)) {
+ continue;
+ }
addRollback(new StartBundleRunnable(bundle));
try {
bundle.stop();
@@ -48,12 +60,34 @@
}
}
else {
- session.getLog().log(LogService.LOG_WARNING, "Could not stop bundle '" + bundleInfos[i].getSymbolicName() + "' because it was not defined int he framework");
+ session.getLog().log(LogService.LOG_WARNING, "Could not stop bundle '" + symbolicName + "' because it was not defined int he framework");
}
}
}
- private class StartBundleRunnable implements Runnable {
+ /**
+ * Determines whether stopping a bundle is strictly needed.
+ *
+ * @param session The current deployment session.
+ * @param symbolicName The symbolic name of the bundle to inspect.
+ *
+ * @return Returns <code>true</code> if <code>Constants.DEPLOYMENTPACKAGE_MISSING</code> is true for the specified bundle in the
+ * source deployment package or if the version of the bundle is the same in both source and target deployment package. Returns
+ * <code>false</code> otherwise.
+ */
+ private boolean omitBundleStop(DeploymentSessionImpl session, String symbolicName) {
+ boolean result = false;
+ BundleInfoImpl sourceBundleInfo = session.getSourceAbstractDeploymentPackage().getBundleInfoByName(symbolicName);
+ BundleInfoImpl targetBundleInfo = session.getSourceAbstractDeploymentPackage().getBundleInfoByName(symbolicName);
+ boolean fixPackageMissing = sourceBundleInfo != null && sourceBundleInfo.isMissing();
+ boolean sameVersion = (targetBundleInfo != null && sourceBundleInfo != null && targetBundleInfo.getVersion().equals(sourceBundleInfo.getVersion()));
+ if (fixPackageMissing || sameVersion) {
+ result = true;
+ }
+ return result;
+ }
+
+ private class StartBundleRunnable implements Runnable {
private final Bundle m_bundle;