Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlyn Normington2012-02-09 10:06:32 -0500
committerGlyn Normington2012-02-10 04:24:17 -0500
commit029ffff4ac55c70b024410055c02435f63a7f28b (patch)
treed800138ecd14b70423089c4e42df02a9e6e09d24
parentfd1828fb7d405a82ccd6d77b0786def250dedfa1 (diff)
downloadorg.eclipse.virgo.kernel-029ffff4ac55c70b024410055c02435f63a7f28b.tar.gz
org.eclipse.virgo.kernel-029ffff4ac55c70b024410055c02435f63a7f28b.tar.xz
org.eclipse.virgo.kernel-029ffff4ac55c70b024410055c02435f63a7f28b.zip
358447: make tests pass
-rw-r--r--org.eclipse.virgo.kernel.deployer.test/src/test/java/org/eclipse/virgo/kernel/deployer/test/PlanDeploymentWithDAGTests.java93
-rw-r--r--org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/deployer/core/internal/PipelinedApplicationDeployer.java16
-rw-r--r--org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/deployer/core/internal/PlanResolver.java3
-rw-r--r--org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/AbstractInstallArtifact.java128
-rw-r--r--org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/ParPlanInstallArtifact.java7
-rw-r--r--org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/ParPlanInstallArtifactFactory.java9
-rw-r--r--org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/PlanInstallArtifactGraphFactory.java11
-rw-r--r--org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/StandardArtifactStateMonitor.java102
-rw-r--r--org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/StandardPlanInstallArtifact.java17
-rw-r--r--org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/bundle/StandardBundleInstallArtifact.java3
-rw-r--r--org.eclipse.virgo.kernel.deployer/src/main/resources/META-INF/spring/deployer-context.xml1
11 files changed, 290 insertions, 100 deletions
diff --git a/org.eclipse.virgo.kernel.deployer.test/src/test/java/org/eclipse/virgo/kernel/deployer/test/PlanDeploymentWithDAGTests.java b/org.eclipse.virgo.kernel.deployer.test/src/test/java/org/eclipse/virgo/kernel/deployer/test/PlanDeploymentWithDAGTests.java
index 61b19f45..f9fc08eb 100644
--- a/org.eclipse.virgo.kernel.deployer.test/src/test/java/org/eclipse/virgo/kernel/deployer/test/PlanDeploymentWithDAGTests.java
+++ b/org.eclipse.virgo.kernel.deployer.test/src/test/java/org/eclipse/virgo/kernel/deployer/test/PlanDeploymentWithDAGTests.java
@@ -187,25 +187,44 @@ public class PlanDeploymentWithDAGTests extends AbstractDeployerIntegrationTest
assertBundlesNotInstalled(this.context.getBundles(), BUNDLE_ONE_SYMBOLIC_NAME);
}
- @Test
+ @Test
// 1a. (@see https://bugs.eclipse.org/bugs/show_bug.cgi?id=365034)
public void planReferencingAnAlreadyInstalledBundleUndeployBundleFirst() throws Exception {
File file = new File("src/test/resources/plan-deployment/simple.bundle.one.jar");
- DeploymentIdentity deploymentId = this.deployer.deploy(file.toURI());
+ DeploymentIdentity bundleDeploymentId = this.deployer.deploy(file.toURI());
assertBundlesInstalled(this.context.getBundles(), BUNDLE_ONE_SYMBOLIC_NAME);
- DeploymentIdentity deploymentIdentity = this.deployer.deploy(new File("src/test/resources/testunscopednonatomicA.plan").toURI());
+ DeploymentIdentity planDeploymentId = this.deployer.deploy(new File("src/test/resources/testunscopednonatomicA.plan").toURI());
assertNoDuplicatesInstalled(this.context.getBundles(), BUNDLE_ONE_SYMBOLIC_NAME);
assertBundlesInstalled(this.context.getBundles(), BUNDLE_ONE_SYMBOLIC_NAME);
- this.deployer.undeploy(deploymentId.getType(), deploymentId.getSymbolicName(), deploymentId.getVersion());
+ this.deployer.undeploy(bundleDeploymentId.getType(), bundleDeploymentId.getSymbolicName(), bundleDeploymentId.getVersion());
assertBundlesInstalled(this.context.getBundles(), BUNDLE_ONE_SYMBOLIC_NAME);
- this.deployer.undeploy(deploymentIdentity);
+ this.deployer.undeploy(planDeploymentId);
assertBundlesNotInstalled(this.context.getBundles(), BUNDLE_ONE_SYMBOLIC_NAME);
}
+ @Test
+ // 1a. (@see https://bugs.eclipse.org/bugs/show_bug.cgi?id=365034)
+ public void planReferencingAnAlreadyInstalledBundleUndeployPlanFirst() throws Exception {
+
+ File file = new File("src/test/resources/plan-deployment/simple.bundle.one.jar");
+ DeploymentIdentity deploymentId = this.deployer.deploy(file.toURI());
+ assertBundlesInstalled(this.context.getBundles(), BUNDLE_ONE_SYMBOLIC_NAME);
+
+ DeploymentIdentity deploymentIdentity = this.deployer.deploy(new File("src/test/resources/testunscopednonatomicA.plan").toURI());
+ assertNoDuplicatesInstalled(this.context.getBundles(), BUNDLE_ONE_SYMBOLIC_NAME);
+ assertBundlesInstalled(this.context.getBundles(), BUNDLE_ONE_SYMBOLIC_NAME);
+
+ this.deployer.undeploy(deploymentIdentity);
+ assertBundlesInstalled(this.context.getBundles(), BUNDLE_ONE_SYMBOLIC_NAME);
+
+ this.deployer.undeploy(deploymentId.getType(), deploymentId.getSymbolicName(), deploymentId.getVersion());
+ assertBundlesNotInstalled(this.context.getBundles(), BUNDLE_ONE_SYMBOLIC_NAME);
+ }
+
private void assertNoDuplicatesInstalled(Bundle[] bundles, String bundleOneSymbolicName) {
List<String> installedBsns = getInstalledBsns(bundles);
int found = 0;
@@ -280,9 +299,25 @@ public class PlanDeploymentWithDAGTests extends AbstractDeployerIntegrationTest
assertBundlesActive(this.context.getBundles(), BUNDLE_ONE_SYMBOLIC_NAME);
this.deployer.undeploy(deploymentId.getType(), deploymentId.getSymbolicName(), deploymentId.getVersion());
+ assertBundlesResolved(this.context.getBundles(), BUNDLE_ONE_SYMBOLIC_NAME);
+
+ this.deployer.undeploy(deploymentIdentity);
+ }
+
+ @Test
+ public void testLifecycleWithPlanReferencingAnAlreadyInstalledBundleUndeployPlanFirst() throws Exception {
+
+ File file = new File("src/test/resources/plan-deployment/simple.bundle.one.jar");
+ DeploymentIdentity deploymentId = this.deployer.deploy(file.toURI());
+ assertBundlesActive(this.context.getBundles(), BUNDLE_ONE_SYMBOLIC_NAME);
+
+ DeploymentIdentity deploymentIdentity = this.deployer.deploy(new File("src/test/resources/testunscopednonatomicA.plan").toURI());
assertBundlesActive(this.context.getBundles(), BUNDLE_ONE_SYMBOLIC_NAME);
this.deployer.undeploy(deploymentIdentity);
+ assertBundlesActive(this.context.getBundles(), BUNDLE_ONE_SYMBOLIC_NAME);
+
+ this.deployer.undeploy(deploymentId.getType(), deploymentId.getSymbolicName(), deploymentId.getVersion());
}
@Test
@@ -380,6 +415,7 @@ public class PlanDeploymentWithDAGTests extends AbstractDeployerIntegrationTest
public void sharedTopLevelBundleActiveActiveStopBundle() throws Exception {
sharedTopLevelBundlePlanActiveBundleActive();
stopBundle();
+ expectBundleStop();
checkEvents();
}
@@ -387,6 +423,7 @@ public class PlanDeploymentWithDAGTests extends AbstractDeployerIntegrationTest
public void sharedTopLevelBundleActiveActiveUninstallBundle() throws Exception {
sharedTopLevelBundlePlanActiveBundleActive();
uninstallBundle();
+ expectBundleStop();
checkEvents();
}
@@ -396,7 +433,7 @@ public class PlanDeploymentWithDAGTests extends AbstractDeployerIntegrationTest
public void sharedTopLevelBundleActiveResolvedStartPlan() throws Exception {
sharedTopLevelBundlePlanActiveBundleResolved();
startPlanA();
- expectBundleStart();
+ // no bundle events expected as ACTIVE plan no-ops when started
checkEvents();
}
@@ -544,6 +581,17 @@ public class PlanDeploymentWithDAGTests extends AbstractDeployerIntegrationTest
expectPlanAUninstall();
checkEvents();
}
+
+ @Test
+ public void sharedTopLevelBundleResolvedResolvedUninstallPlanUninstallBundle() throws Exception {
+ sharedTopLevelBundlePlanResolvedBundleResolved();
+ uninstallPlanA();
+ uninstallBundle();
+ expectPlanAUninstall();
+ expectBundleUninstall();
+ checkEvents();
+ }
+
// twoPlansReferencingASharedBundleActiveActive
@@ -672,6 +720,8 @@ public class PlanDeploymentWithDAGTests extends AbstractDeployerIntegrationTest
public void sharedTopLevelPlanActiveActiveStopChildPlan() throws Exception {
sharedTopLevelPlanChildActiveParentActive();
stopChildPlan();
+ expectChildPlanStop();
+ expectBundleStop();
checkEvents();
}
@@ -679,6 +729,8 @@ public class PlanDeploymentWithDAGTests extends AbstractDeployerIntegrationTest
public void sharedTopLevelPlanActiveActiveUninstallChildPlan() throws Exception {
sharedTopLevelPlanChildActiveParentActive();
uninstallChildPlan();
+ expectChildPlanStop();
+ expectBundleStop();
checkEvents();
}
@@ -720,6 +772,7 @@ public class PlanDeploymentWithDAGTests extends AbstractDeployerIntegrationTest
sharedTopLevelPlanChildActiveParentResolved();
stopChildPlan();
expectChildPlanStop();
+ expectBundleStop();
checkEvents();
}
@@ -728,6 +781,7 @@ public class PlanDeploymentWithDAGTests extends AbstractDeployerIntegrationTest
sharedTopLevelPlanChildActiveParentResolved();
uninstallChildPlan();
expectChildPlanStop();
+ expectBundleStop();
checkEvents();
}
@@ -761,6 +815,7 @@ public class PlanDeploymentWithDAGTests extends AbstractDeployerIntegrationTest
sharedTopLevelPlanChildResolvedParentActive();
startChildPlan();
expectChildPlanStart();
+ expectBundleStart();
checkEvents();
}
@@ -809,6 +864,7 @@ public class PlanDeploymentWithDAGTests extends AbstractDeployerIntegrationTest
sharedTopLevelPlanChildResolvedParentResolved();
startChildPlan();
expectChildPlanStart();
+ expectBundleStart();
checkEvents();
}
@@ -861,6 +917,17 @@ public class PlanDeploymentWithDAGTests extends AbstractDeployerIntegrationTest
expectBundleUninstall();
checkEvents();
}
+
+ @Test
+ public void sharedTopLevelPlanResolvedResolvedUninstallChildPlanUninstallParentPlan() throws Exception {
+ sharedTopLevelPlanChildResolvedParentResolved();
+ uninstallChildPlan();
+ uninstallParentPlan();
+ expectChildPlanUninstall();
+ expectParentPlanUninstall();
+ expectBundleUninstall();
+ checkEvents();
+ }
// twoPlansReferencingASharedPlanActiveActive
@@ -1287,13 +1354,13 @@ public class PlanDeploymentWithDAGTests extends AbstractDeployerIntegrationTest
private void sharedTopLevelBundlePlanActiveBundleResolved() throws DeploymentException {
deploySharedTopLevelBundle();
stopBundle();
- stopBundle();
clearEvents();
}
private void sharedTopLevelBundlePlanResolvedBundleActive() throws DeploymentException {
deploySharedTopLevelBundle();
stopPlanA();
+ startBundle();
clearEvents();
}
@@ -1395,12 +1462,20 @@ public class PlanDeploymentWithDAGTests extends AbstractDeployerIntegrationTest
}
static void assertBundlesActive(Bundle[] bundles, String... bsns) {
+ assertBundlesInState(Bundle.ACTIVE, bundles, bsns);
+ }
+
+ static void assertBundlesResolved(Bundle[] bundles, String... bsns) {
+ assertBundlesInState(Bundle.RESOLVED, bundles, bsns);
+ }
+
+ private static void assertBundlesInState(int state, Bundle[] bundles, String... bsns) {
for (String bsn : bsns) {
boolean found = false;
for (Bundle bundle : bundles) {
if (bsn.equals(bundle.getSymbolicName())) {
found = true;
- assertEquals(Bundle.ACTIVE, bundle.getState());
+ assertEquals(state, bundle.getState());
}
}
assertTrue(found);
@@ -1416,7 +1491,7 @@ public class PlanDeploymentWithDAGTests extends AbstractDeployerIntegrationTest
Set<ArtifactLifecycleEvent> missingEvents = Sets.difference(expectedEventSet, actualEventSet);
assertTrue(extraEvents.size() + " more events were received than expected: " + extraEvents, extraEvents.isEmpty());
- assertTrue("There were " + missingEvents.size() + " missing events: " + missingEvents, missingEvents.isEmpty());
+ assertTrue(missingEvents.size() + " more events were expected than received: " + missingEvents, missingEvents.isEmpty());
}
}
diff --git a/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/deployer/core/internal/PipelinedApplicationDeployer.java b/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/deployer/core/internal/PipelinedApplicationDeployer.java
index 2d2256a0..c9ceb1cc 100644
--- a/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/deployer/core/internal/PipelinedApplicationDeployer.java
+++ b/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/deployer/core/internal/PipelinedApplicationDeployer.java
@@ -37,6 +37,7 @@ import org.eclipse.virgo.kernel.install.artifact.ArtifactIdentityDeterminer;
import org.eclipse.virgo.kernel.install.artifact.InstallArtifact;
import org.eclipse.virgo.kernel.install.artifact.InstallArtifactGraphInclosure;
import org.eclipse.virgo.kernel.install.artifact.PlanInstallArtifact;
+import org.eclipse.virgo.kernel.install.artifact.internal.AbstractInstallArtifact;
import org.eclipse.virgo.kernel.install.environment.InstallEnvironment;
import org.eclipse.virgo.kernel.install.environment.InstallEnvironmentFactory;
import org.eclipse.virgo.kernel.install.pipeline.Pipeline;
@@ -298,7 +299,9 @@ final class PipelinedApplicationDeployer implements ApplicationDeployer, Applica
private DeploymentIdentity addGraphToModel(URI location, GraphNode<InstallArtifact> installGraph) throws DuplicateFileNameException,
DuplicateLocationException, DuplicateDeploymentIdentityException, DeploymentException {
- return this.ram.add(location, installGraph.getValue());
+ InstallArtifact installArtifact = installGraph.getValue();
+ ((AbstractInstallArtifact) installArtifact).setTopLevelDeployed();
+ return this.ram.add(location, installArtifact);
}
/**
@@ -615,14 +618,9 @@ final class PipelinedApplicationDeployer implements ApplicationDeployer, Applica
this.ram.delete(deploymentIdentity);
- // Avoid uninstalling an artifact which is shared by a plan.
- if (ExistingNodeLocator.findSharedNode((GCRoots) this.ram, installArtifact.getGraph()) == null) {
- stopArtifact(installArtifact);
- uninstallArtifact(installArtifact);
- return location;
- } else {
- return null;
- }
+ stopArtifact(installArtifact);
+ uninstallArtifact(installArtifact);
+ return location;
}
}
}
diff --git a/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/deployer/core/internal/PlanResolver.java b/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/deployer/core/internal/PlanResolver.java
index 33e69736..8881f354 100644
--- a/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/deployer/core/internal/PlanResolver.java
+++ b/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/deployer/core/internal/PlanResolver.java
@@ -101,7 +101,8 @@ public class PlanResolver implements Transformer {
GraphNode<InstallArtifact> childInstallNode = obtainInstallArtifactGraph(artifactSpecification, scopeName,
planInstallArtifact.getProvisioning());
- boolean newNode = childInstallNode.getParents().isEmpty();
+ boolean newNode = childInstallNode.getParents().isEmpty()
+ && !(((AbstractInstallArtifact) childInstallNode.getValue()).getTopLevelDeployed());
graph.addChild(childInstallNode);
if (newNode) {
// Put child into the INSTALLING state as Transformers (like this) are after the
diff --git a/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/AbstractInstallArtifact.java b/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/AbstractInstallArtifact.java
index ffaf3af3..0389caba 100644
--- a/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/AbstractInstallArtifact.java
+++ b/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/AbstractInstallArtifact.java
@@ -68,6 +68,15 @@ public abstract class AbstractInstallArtifact implements GraphAssociableInstallA
private volatile boolean isRefreshing;
+ // Whether or not this artifact was the target of a deployment operation (rather than a child of such a target).
+ private boolean isTopLevelDeployed = false;
+
+ /*
+ * If isTopLevelDeployed is true, whether or not this artifact is ACTIVE (or STARTING) from the perspective of the
+ * deployer operations that have been performed on it. If isTopLevelDeployed is false, this flag is undefined.
+ */
+ private boolean isTopLevelActive = false;
+
/**
* Construct an {@link AbstractInstallArtifact} from the given type, name, version, {@link ArtifactFS}, and
* {@link ArtifactState}, none of which may be null.
@@ -202,6 +211,9 @@ public abstract class AbstractInstallArtifact implements GraphAssociableInstallA
signal.signalSuccessfulCompletion();
}
} else {
+ if (!hasStartingParent()) {
+ topLevelStart();
+ }
pushThreadContext();
try {
boolean stateChanged = this.artifactStateMonitor.onStarting(this);
@@ -311,6 +323,7 @@ public abstract class AbstractInstallArtifact implements GraphAssociableInstallA
}
private final void asyncStartFailed(Throwable cause) {
+ topLevelStop();
pushThreadContext();
try {
this.artifactStateMonitor.onStartFailed(this, cause);
@@ -322,6 +335,7 @@ public abstract class AbstractInstallArtifact implements GraphAssociableInstallA
}
private final void asyncStartAborted() {
+ topLevelStop();
pushThreadContext();
try {
this.artifactStateMonitor.onStartAborted(this);
@@ -356,13 +370,26 @@ public abstract class AbstractInstallArtifact implements GraphAssociableInstallA
protected boolean shouldStop() {
/*
- * This artifact should stop if it was explicitly stopped independently of its parents (that is, it has no
- * STOPPING parents) or it has no parents that are ACTIVE or STARTING.
+ * The artifact should stop if it was explicitly stopped (not via a parent) or if it was implicitly stopped (via
+ * a parents) and it has no parents that are ACTIVE or STARTING.
*/
- return !hasStoppingParent() || !hasActiveParent();
+ boolean explicitStop = explicitStop();
+ if (explicitStop) {
+ topLevelStop();
+ }
+ return explicitStop || !hasActiveParent();
+ }
+
+ public boolean explicitStop() {
+ return !hasStoppingParent();
}
private boolean hasActiveParent() {
+ synchronized (this.monitor) {
+ if (this.isTopLevelDeployed && this.isTopLevelActive) {
+ return true;
+ }
+ }
for (GraphNode<InstallArtifact> parent : this.graph.getParents()) {
State parentState = parent.getValue().getState();
if (parentState.equals(State.ACTIVE) || parentState.equals(State.STARTING)) {
@@ -373,15 +400,45 @@ public abstract class AbstractInstallArtifact implements GraphAssociableInstallA
}
private boolean hasStoppingParent() {
+ return hasParentInState(State.STOPPING);
+ }
+
+ private boolean hasParentInState(State state) {
for (GraphNode<InstallArtifact> parent : this.graph.getParents()) {
State parentState = parent.getValue().getState();
- if (parentState.equals(State.STOPPING)) {
+ if (parentState.equals(state)) {
return true;
}
}
return false;
}
+ private void topLevelStop() {
+ synchronized (this.monitor) {
+ if (this.isTopLevelDeployed) {
+ this.isTopLevelActive = false;
+ }
+ }
+ }
+
+ protected boolean hasStartingParent() {
+ for (GraphNode<InstallArtifact> parent : this.graph.getParents()) {
+ State parentState = parent.getValue().getState();
+ if (parentState.equals(State.STARTING)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ protected void topLevelStart() {
+ synchronized (this.monitor) {
+ if (this.isTopLevelDeployed) {
+ this.isTopLevelActive = true;
+ }
+ }
+ }
+
/**
* @see stop
*/
@@ -392,8 +449,8 @@ public abstract class AbstractInstallArtifact implements GraphAssociableInstallA
*/
@Override
public void uninstall() throws DeploymentException {
- if (getState().equals(State.STARTING) || getState().equals(State.ACTIVE) || getState().equals(State.RESOLVED)
- || getState().equals(State.INSTALLED) || getState().equals(State.INITIAL)) {
+ if ((getState().equals(State.STARTING) || getState().equals(State.ACTIVE) || getState().equals(State.RESOLVED)
+ || getState().equals(State.INSTALLED) || getState().equals(State.INITIAL))) {
try {
if (!getState().equals(State.INITIAL)) {
pushThreadContext();
@@ -401,12 +458,14 @@ public abstract class AbstractInstallArtifact implements GraphAssociableInstallA
if (getState().equals(State.ACTIVE) || getState().equals(State.STARTING)) {
stop();
}
- this.artifactStateMonitor.onUninstalling(this);
- try {
- doUninstall();
- this.artifactStateMonitor.onUninstalled(this);
- } catch (DeploymentException e) {
- this.artifactStateMonitor.onUninstallFailed(this, e);
+ if (shouldUninstall()) {
+ this.artifactStateMonitor.onUninstalling(this);
+ try {
+ doUninstall();
+ this.artifactStateMonitor.onUninstalled(this);
+ } catch (DeploymentException e) {
+ this.artifactStateMonitor.onUninstallFailed(this, e);
+ }
}
} finally {
popThreadContext();
@@ -418,6 +477,39 @@ public abstract class AbstractInstallArtifact implements GraphAssociableInstallA
}
}
+ private boolean shouldUninstall() {
+ boolean explicitUninstall = explicitUninstall();
+ if (explicitUninstall) {
+ topLevelUninstall();
+ }
+ return allParentsInState(State.UNINSTALLING);
+ }
+
+ private boolean allParentsInState(State state) {
+ for (GraphNode<InstallArtifact> parent : this.graph.getParents()) {
+ State parentState = parent.getValue().getState();
+ if (!parentState.equals(state)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public boolean explicitUninstall() {
+ return !hasUninstallingParent();
+ }
+
+ private boolean hasUninstallingParent() {
+ return hasParentInState(State.UNINSTALLING);
+ }
+
+ private void topLevelUninstall() {
+ synchronized (this.monitor) {
+ this.isTopLevelDeployed = false;
+ }
+
+ }
+
/**
* @see uninstall
*/
@@ -562,4 +654,16 @@ public abstract class AbstractInstallArtifact implements GraphAssociableInstallA
}
}
+ public void setTopLevelDeployed() {
+ synchronized (this.monitor) {
+ this.isTopLevelDeployed = true;
+ }
+ }
+
+ public boolean getTopLevelDeployed() {
+ synchronized (this.monitor) {
+ return this.isTopLevelDeployed;
+ }
+ }
+
}
diff --git a/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/ParPlanInstallArtifact.java b/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/ParPlanInstallArtifact.java
index be2a9d9b..d0bb3f3b 100644
--- a/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/ParPlanInstallArtifact.java
+++ b/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/ParPlanInstallArtifact.java
@@ -22,7 +22,6 @@ import org.eclipse.virgo.kernel.artifact.fs.ArtifactFSEntry;
import org.eclipse.virgo.kernel.artifact.plan.PlanDescriptor.Provisioning;
import org.eclipse.virgo.kernel.deployer.core.DeployerLogEvents;
import org.eclipse.virgo.kernel.deployer.core.DeploymentException;
-import org.eclipse.virgo.kernel.deployer.model.GCRoots;
import org.eclipse.virgo.kernel.install.artifact.ArtifactIdentity;
import org.eclipse.virgo.kernel.install.artifact.ArtifactIdentityDeterminer;
import org.eclipse.virgo.kernel.install.artifact.ArtifactStorage;
@@ -75,10 +74,10 @@ final class ParPlanInstallArtifact extends StandardPlanInstallArtifact {
@NonNull ScopeFactory scopeFactory, @NonNull EventLogger eventLogger, @NonNull InstallArtifactGraphFactory bundleInstallArtifactGraphFactory,
@NonNull InstallArtifactRefreshHandler refreshHandler, String repositoryName,
@NonNull InstallArtifactGraphFactory configInstallArtifactGraphFactory, @NonNull ArtifactStorageFactory artifactStorageFactory,
- @NonNull ArtifactIdentityDeterminer artifactIdentityDeterminer, @NonNull InstallArtifactGraphFactory planInstallArtifactGraphFactory,
- GCRoots gcRoots) throws DeploymentException {
+ @NonNull ArtifactIdentityDeterminer artifactIdentityDeterminer, @NonNull InstallArtifactGraphFactory planInstallArtifactGraphFactory)
+ throws DeploymentException {
super(identity, true, true, Provisioning.AUTO, artifactStorage, artifactStateMonitor, scopeServiceRepository, scopeFactory, eventLogger,
- refreshHandler, repositoryName, EMPTY_ARTIFACT_SPECIFICATION_LIST, gcRoots);
+ refreshHandler, repositoryName, EMPTY_ARTIFACT_SPECIFICATION_LIST);
this.artifactStorageFactory = artifactStorageFactory;
this.configInstallArtifactGraphFactory = configInstallArtifactGraphFactory;
diff --git a/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/ParPlanInstallArtifactFactory.java b/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/ParPlanInstallArtifactFactory.java
index acc85119..a3fa6bd4 100644
--- a/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/ParPlanInstallArtifactFactory.java
+++ b/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/ParPlanInstallArtifactFactory.java
@@ -12,11 +12,7 @@
package org.eclipse.virgo.kernel.install.artifact.internal;
-import org.osgi.framework.BundleContext;
-
-
import org.eclipse.virgo.kernel.deployer.core.DeploymentException;
-import org.eclipse.virgo.kernel.deployer.model.GCRoots;
import org.eclipse.virgo.kernel.install.artifact.ArtifactIdentity;
import org.eclipse.virgo.kernel.install.artifact.ArtifactIdentityDeterminer;
import org.eclipse.virgo.kernel.install.artifact.ArtifactStorage;
@@ -26,6 +22,7 @@ import org.eclipse.virgo.kernel.install.artifact.internal.bundle.BundleInstallAr
import org.eclipse.virgo.kernel.serviceability.NonNull;
import org.eclipse.virgo.kernel.shim.scope.ScopeFactory;
import org.eclipse.virgo.medic.eventlog.EventLogger;
+import org.osgi.framework.BundleContext;
/**
* A factory for creating {@link ParPlanInstallArtifact} instances.
@@ -75,10 +72,10 @@ final class ParPlanInstallArtifactFactory {
this.planInstallArtifactGraphFactory = planInstallArtifactGraphFactory;
}
- ParPlanInstallArtifact createParPlanInstallArtifact(@NonNull ArtifactIdentity artifactIdentity, @NonNull ArtifactStorage artifactStorage, String repositoryName, GCRoots gcRoots) throws DeploymentException {
+ ParPlanInstallArtifact createParPlanInstallArtifact(@NonNull ArtifactIdentity artifactIdentity, @NonNull ArtifactStorage artifactStorage, String repositoryName) throws DeploymentException {
ArtifactStateMonitor artifactStateMonitor = new StandardArtifactStateMonitor(this.bundleContext);
return new ParPlanInstallArtifact(artifactIdentity, artifactStorage, artifactStateMonitor, scopeServiceRepository, scopeFactory, eventLogger,
bundleInstallArtifactGraphFactory, refreshHandler, repositoryName, this.configInstallArtifactGraphFactory,
- this.artifactStorageFactory, this.artifactIdentityDeterminer, this.planInstallArtifactGraphFactory, gcRoots);
+ this.artifactStorageFactory, this.artifactIdentityDeterminer, this.planInstallArtifactGraphFactory);
}
}
diff --git a/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/PlanInstallArtifactGraphFactory.java b/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/PlanInstallArtifactGraphFactory.java
index deb131e6..fa773111 100644
--- a/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/PlanInstallArtifactGraphFactory.java
+++ b/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/PlanInstallArtifactGraphFactory.java
@@ -23,7 +23,6 @@ import org.eclipse.virgo.kernel.artifact.plan.PlanDescriptor;
import org.eclipse.virgo.kernel.artifact.plan.PlanDescriptor.Provisioning;
import org.eclipse.virgo.kernel.artifact.plan.PlanReader;
import org.eclipse.virgo.kernel.deployer.core.DeploymentException;
-import org.eclipse.virgo.kernel.deployer.model.GCRoots;
import org.eclipse.virgo.kernel.install.artifact.ArtifactIdentity;
import org.eclipse.virgo.kernel.install.artifact.ArtifactIdentityDeterminer;
import org.eclipse.virgo.kernel.install.artifact.ArtifactStorage;
@@ -65,21 +64,17 @@ final class PlanInstallArtifactGraphFactory extends AbstractArtifactGraphFactory
private final ParPlanInstallArtifactFactory parFactory;
- private final GCRoots gcRoots;
-
public PlanInstallArtifactGraphFactory(@NonNull BundleContext bundleContext, @NonNull ScopeServiceRepository scopeServiceRepository,
@NonNull ScopeFactory scopeFactory, @NonNull EventLogger eventLogger,
@NonNull BundleInstallArtifactGraphFactory bundleInstallArtifactGraphFactory, @NonNull InstallArtifactRefreshHandler refreshHandler,
@NonNull ConfigInstallArtifactGraphFactory configInstallArtifactGraphFactory, @NonNull ArtifactStorageFactory artifactStorageFactory,
- @NonNull ArtifactIdentityDeterminer artifactIdentityDeterminer, @NonNull DirectedAcyclicGraph<InstallArtifact> dag,
- @NonNull GCRoots gcRoots) {
+ @NonNull ArtifactIdentityDeterminer artifactIdentityDeterminer, @NonNull DirectedAcyclicGraph<InstallArtifact> dag) {
super(dag);
this.bundleContext = bundleContext;
this.scopeServiceRepository = scopeServiceRepository;
this.scopeFactory = scopeFactory;
this.eventLogger = eventLogger;
this.refreshHandler = refreshHandler;
- this.gcRoots = gcRoots;
this.parFactory = new ParPlanInstallArtifactFactory(eventLogger, bundleContext, bundleInstallArtifactGraphFactory, scopeServiceRepository,
scopeFactory, refreshHandler, configInstallArtifactGraphFactory, artifactStorageFactory, artifactIdentityDeterminer, this);
@@ -103,7 +98,7 @@ final class PlanInstallArtifactGraphFactory extends AbstractArtifactGraphFactory
private GraphNode<InstallArtifact> createParGraph(ArtifactIdentity artifactIdentity, ArtifactStorage artifactStorage, String repositoryName)
throws DeploymentException {
- ParPlanInstallArtifact parArtifact = this.parFactory.createParPlanInstallArtifact(artifactIdentity, artifactStorage, repositoryName, this.gcRoots);
+ ParPlanInstallArtifact parArtifact = this.parFactory.createParPlanInstallArtifact(artifactIdentity, artifactStorage, repositoryName);
return constructAssociatedGraphNode(parArtifact);
}
@@ -129,7 +124,7 @@ final class PlanInstallArtifactGraphFactory extends AbstractArtifactGraphFactory
StandardPlanInstallArtifact planInstallArtifact = new StandardPlanInstallArtifact(artifactIdentity, planDescriptor.getAtomic(),
planDescriptor.getScoped(), resultantProvisioning, artifactStorage, new StandardArtifactStateMonitor(this.bundleContext),
this.scopeServiceRepository, this.scopeFactory, this.eventLogger, this.refreshHandler, repositoryName,
- planDescriptor.getArtifactSpecifications(), this.gcRoots);
+ planDescriptor.getArtifactSpecifications());
return constructAssociatedGraphNode(planInstallArtifact);
}
diff --git a/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/StandardArtifactStateMonitor.java b/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/StandardArtifactStateMonitor.java
index 751b24cf..b5089419 100644
--- a/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/StandardArtifactStateMonitor.java
+++ b/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/StandardArtifactStateMonitor.java
@@ -104,14 +104,17 @@ public class StandardArtifactStateMonitor implements ArtifactStateMonitor {
* {@inheritDoc}
*/
public void onInstalling(InstallArtifact installArtifact) throws DeploymentException {
- if (this.artifactState.setInstalling()) {
- List<OsgiServiceHolder<InstallArtifactLifecycleListener>> listenerHolders = getListenerHolders();
- try {
- for (InstallArtifactLifecycleListener listener : getListeners(listenerHolders)) {
- listener.onInstalling(installArtifact);
+ State state = this.artifactState.getState();
+ if (state.equals(State.INITIAL)) {
+ if (this.artifactState.setInstalling()) {
+ List<OsgiServiceHolder<InstallArtifactLifecycleListener>> listenerHolders = getListenerHolders();
+ try {
+ for (InstallArtifactLifecycleListener listener : getListeners(listenerHolders)) {
+ listener.onInstalling(installArtifact);
+ }
+ } finally {
+ ungetListeners(listenerHolders);
}
- } finally {
- ungetListeners(listenerHolders);
}
}
}
@@ -120,14 +123,17 @@ public class StandardArtifactStateMonitor implements ArtifactStateMonitor {
* {@inheritDoc}
*/
public void onInstallFailed(InstallArtifact installArtifact) throws DeploymentException {
- if (this.artifactState.setInitial()) {
- List<OsgiServiceHolder<InstallArtifactLifecycleListener>> listenerHolders = getListenerHolders();
- try {
- for (InstallArtifactLifecycleListener listener : getListeners(listenerHolders)) {
- listener.onInstallFailed(installArtifact);
+ State state = this.artifactState.getState();
+ if (state.equals(State.INSTALLING)) {
+ if (this.artifactState.setInitial()) {
+ List<OsgiServiceHolder<InstallArtifactLifecycleListener>> listenerHolders = getListenerHolders();
+ try {
+ for (InstallArtifactLifecycleListener listener : getListeners(listenerHolders)) {
+ listener.onInstallFailed(installArtifact);
+ }
+ } finally {
+ ungetListeners(listenerHolders);
}
- } finally {
- ungetListeners(listenerHolders);
}
}
}
@@ -136,14 +142,17 @@ public class StandardArtifactStateMonitor implements ArtifactStateMonitor {
* {@inheritDoc}
*/
public void onInstalled(InstallArtifact installArtifact) throws DeploymentException {
- if (this.artifactState.setInstalled()) {
- List<OsgiServiceHolder<InstallArtifactLifecycleListener>> listenerHolders = getListenerHolders();
- try {
- for (InstallArtifactLifecycleListener listener : getListeners(listenerHolders)) {
- listener.onInstalled(installArtifact);
+ State state = this.artifactState.getState();
+ if (state.equals(State.INITIAL) || state.equals(State.INSTALLING)) {
+ if (this.artifactState.setInstalled()) {
+ List<OsgiServiceHolder<InstallArtifactLifecycleListener>> listenerHolders = getListenerHolders();
+ try {
+ for (InstallArtifactLifecycleListener listener : getListeners(listenerHolders)) {
+ listener.onInstalled(installArtifact);
+ }
+ } finally {
+ ungetListeners(listenerHolders);
}
- } finally {
- ungetListeners(listenerHolders);
}
}
}
@@ -152,14 +161,17 @@ public class StandardArtifactStateMonitor implements ArtifactStateMonitor {
* {@inheritDoc}
*/
public void onResolving(InstallArtifact installArtifact) throws DeploymentException {
- if (this.artifactState.setResolving()) {
- List<OsgiServiceHolder<InstallArtifactLifecycleListener>> listenerHolders = getListenerHolders();
- try {
- for (InstallArtifactLifecycleListener listener : getListeners(listenerHolders)) {
- listener.onResolving(installArtifact);
+ State state = this.artifactState.getState();
+ if (state.equals(State.INITIAL) || state.equals(State.INSTALLING) || state.equals(State.INSTALLED)) {
+ if (this.artifactState.setResolving()) {
+ List<OsgiServiceHolder<InstallArtifactLifecycleListener>> listenerHolders = getListenerHolders();
+ try {
+ for (InstallArtifactLifecycleListener listener : getListeners(listenerHolders)) {
+ listener.onResolving(installArtifact);
+ }
+ } finally {
+ ungetListeners(listenerHolders);
}
- } finally {
- ungetListeners(listenerHolders);
}
}
}
@@ -168,14 +180,17 @@ public class StandardArtifactStateMonitor implements ArtifactStateMonitor {
* {@inheritDoc}
*/
public void onResolveFailed(InstallArtifact installArtifact) throws DeploymentException {
- if (this.artifactState.setInstalled()) {
- List<OsgiServiceHolder<InstallArtifactLifecycleListener>> listenerHolders = getListenerHolders();
- try {
- for (InstallArtifactLifecycleListener listener : getListeners(listenerHolders)) {
- listener.onResolveFailed(installArtifact);
+ State state = this.artifactState.getState();
+ if (state.equals(State.INITIAL) || state.equals(State.INSTALLING) || state.equals(State.INSTALLED) || state.equals(State.RESOLVING) || state.equals(State.STOPPING)) {
+ if (this.artifactState.setInstalled()) {
+ List<OsgiServiceHolder<InstallArtifactLifecycleListener>> listenerHolders = getListenerHolders();
+ try {
+ for (InstallArtifactLifecycleListener listener : getListeners(listenerHolders)) {
+ listener.onResolveFailed(installArtifact);
+ }
+ } finally {
+ ungetListeners(listenerHolders);
}
- } finally {
- ungetListeners(listenerHolders);
}
}
}
@@ -184,14 +199,17 @@ public class StandardArtifactStateMonitor implements ArtifactStateMonitor {
* {@inheritDoc}
*/
public void onResolved(InstallArtifact installArtifact) throws DeploymentException {
- if (this.artifactState.setResolved()) {
- List<OsgiServiceHolder<InstallArtifactLifecycleListener>> listenerHolders = getListenerHolders();
- try {
- for (InstallArtifactLifecycleListener listener : getListeners(listenerHolders)) {
- listener.onResolved(installArtifact);
+ State state = this.artifactState.getState();
+ if (state.equals(State.INITIAL) || state.equals(State.INSTALLING) || state.equals(State.INSTALLED) || state.equals(State.RESOLVING) || state.equals(State.STOPPING)) {
+ if (this.artifactState.setResolved()) {
+ List<OsgiServiceHolder<InstallArtifactLifecycleListener>> listenerHolders = getListenerHolders();
+ try {
+ for (InstallArtifactLifecycleListener listener : getListeners(listenerHolders)) {
+ listener.onResolved(installArtifact);
+ }
+ } finally {
+ ungetListeners(listenerHolders);
}
- } finally {
- ungetListeners(listenerHolders);
}
}
}
diff --git a/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/StandardPlanInstallArtifact.java b/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/StandardPlanInstallArtifact.java
index 19eda12e..fdb38554 100644
--- a/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/StandardPlanInstallArtifact.java
+++ b/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/StandardPlanInstallArtifact.java
@@ -21,8 +21,6 @@ import org.eclipse.virgo.kernel.core.AbortableSignal;
import org.eclipse.virgo.kernel.deployer.core.DeployerLogEvents;
import org.eclipse.virgo.kernel.deployer.core.DeploymentException;
import org.eclipse.virgo.kernel.deployer.core.internal.AbortableSignalJunction;
-import org.eclipse.virgo.kernel.deployer.core.internal.ExistingNodeLocator;
-import org.eclipse.virgo.kernel.deployer.model.GCRoots;
import org.eclipse.virgo.kernel.install.artifact.ArtifactIdentity;
import org.eclipse.virgo.kernel.install.artifact.ArtifactStorage;
import org.eclipse.virgo.kernel.install.artifact.InstallArtifact;
@@ -70,13 +68,11 @@ public class StandardPlanInstallArtifact extends AbstractInstallArtifact impleme
private Scope applicationScope;
- private final GCRoots gcRoots;
-
protected StandardPlanInstallArtifact(@NonNull ArtifactIdentity artifactIdentity, boolean atomic, boolean scoped,
@NonNull Provisioning provisioning, @NonNull ArtifactStorage artifactStorage, @NonNull ArtifactStateMonitor artifactStateMonitor,
@NonNull ScopeServiceRepository scopeServiceRepository, @NonNull ScopeFactory scopeFactory, @NonNull EventLogger eventLogger,
- @NonNull InstallArtifactRefreshHandler refreshHandler, String repositoryName, List<ArtifactSpecification> artifactSpecifications,
- GCRoots gcRoots) throws DeploymentException {
+ @NonNull InstallArtifactRefreshHandler refreshHandler, String repositoryName, List<ArtifactSpecification> artifactSpecifications)
+ throws DeploymentException {
super(artifactIdentity, artifactStorage, artifactStateMonitor, repositoryName, eventLogger);
policeNestedScopes(artifactIdentity, scoped, eventLogger);
@@ -92,7 +88,6 @@ public class StandardPlanInstallArtifact extends AbstractInstallArtifact impleme
}
this.provisioning = provisioning;
this.artifactSpecifications = artifactSpecifications;
- this.gcRoots = gcRoots;
}
private void policeNestedScopes(ArtifactIdentity artifactIdentity, boolean scoped, EventLogger eventLogger) throws DeploymentException {
@@ -167,7 +162,7 @@ public class StandardPlanInstallArtifact extends AbstractInstallArtifact impleme
for (GraphNode<InstallArtifact> child : getChildrenSnapshot()) {
getGraph().removeChild(child);
// Avoid uninstalling shared child
- if (ExistingNodeLocator.findSharedNode(this.gcRoots, child) == null) {
+ if (!inUse(child)) {
try {
child.getValue().uninstall();
} catch (DeploymentException e) {
@@ -180,6 +175,12 @@ public class StandardPlanInstallArtifact extends AbstractInstallArtifact impleme
}
}
+ private boolean inUse(GraphNode<InstallArtifact> child) {
+ AbstractInstallArtifact installArtifact = (AbstractInstallArtifact) child.getValue();
+ boolean isTopLevelDeployed = installArtifact.getTopLevelDeployed();
+ return isTopLevelDeployed || !child.getParents().isEmpty();
+ }
+
public void scope() throws DeploymentException {
if (isScoped()) {
List<InstallArtifact> scopeMembers = new PlanMemberCollector().collectPlanMembers(this);
diff --git a/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/bundle/StandardBundleInstallArtifact.java b/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/bundle/StandardBundleInstallArtifact.java
index 379e1247..e2297afe 100644
--- a/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/bundle/StandardBundleInstallArtifact.java
+++ b/org.eclipse.virgo.kernel.deployer/src/main/java/org/eclipse/virgo/kernel/install/artifact/internal/bundle/StandardBundleInstallArtifact.java
@@ -253,6 +253,9 @@ final class StandardBundleInstallArtifact extends AbstractInstallArtifact implem
*/
@Override
public void start(AbortableSignal signal) throws DeploymentException {
+ if (!hasStartingParent()) {
+ topLevelStart();
+ }
/*
* Do not call super.start(signal) as it is essential that the starting event is driven under the bundle
* lifecycle event so the listeners see a suitable bundle state.
diff --git a/org.eclipse.virgo.kernel.deployer/src/main/resources/META-INF/spring/deployer-context.xml b/org.eclipse.virgo.kernel.deployer/src/main/resources/META-INF/spring/deployer-context.xml
index d4998bf1..a70ca508 100644
--- a/org.eclipse.virgo.kernel.deployer/src/main/resources/META-INF/spring/deployer-context.xml
+++ b/org.eclipse.virgo.kernel.deployer/src/main/resources/META-INF/spring/deployer-context.xml
@@ -296,7 +296,6 @@
<beans:constructor-arg ref="artifactStorageFactory" />
<beans:constructor-arg ref="artifactIdentityDeterminer" />
<beans:constructor-arg ref="installArtifactGraph" />
- <beans:constructor-arg ref="runtimeArtifactModel" />
</beans:bean>
</service>

Back to the top