Modified: aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResourceInstaller.java URL: http://svn.apache.org/viewvc/aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResourceInstaller.java?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResourceInstaller.java (original) +++ aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResourceInstaller.java Wed Apr 13 18:41:23 2016 @@ -83,15 +83,15 @@ public class SubsystemResourceInstaller } Comparator<Resource> comparator = new InstallResourceComparator(); // Install dependencies first if appropriate... - if (Utils.isProvisionDependenciesInstall(subsystem)) { - new InstallDependencies().install(subsystem, this.subsystem, coordination); + if (!subsystem.isRoot() && Utils.isProvisionDependenciesInstall(subsystem)) { + new InstallDependencies().install(subsystem, this.subsystem, coordination); } // ...followed by content. // Simulate installation of shared content so that necessary relationships are established. - for (Resource content : subsystem.getResource().getSharedContent()) { - ResourceInstaller.newInstance(coordination, content, subsystem).install(); - } - // Now take care of the installable content. + for (Resource content : subsystem.getResource().getSharedContent()) { + ResourceInstaller.newInstance(coordination, content, subsystem).install(); + } + // Now take care of the installable content. if (State.INSTALLING.equals(subsystem.getState())) { List<Resource> installableContent = new ArrayList<Resource>(subsystem.getResource().getInstallableContent()); Collections.sort(installableContent, comparator); @@ -101,7 +101,7 @@ public class SubsystemResourceInstaller // Only brand new subsystems should have acquired the INSTALLING state, // in which case an INSTALLED event must be propagated. if (State.INSTALLING.equals(subsystem.getState()) && - Utils.isProvisionDependenciesInstall(subsystem)) { + Utils.isProvisionDependenciesInstall(subsystem)) { subsystem.setState(State.INSTALLED); } else { @@ -112,7 +112,7 @@ public class SubsystemResourceInstaller } private BasicSubsystem installRawSubsystemResource(RawSubsystemResource resource) throws Exception { - SubsystemResource subsystemResource = new SubsystemResource(resource, provisionTo); + SubsystemResource subsystemResource = new SubsystemResource(resource, provisionTo, coordination); return installSubsystemResource(subsystemResource); }
Modified: aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/UninstallAction.java URL: http://svn.apache.org/viewvc/aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/UninstallAction.java?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/UninstallAction.java (original) +++ aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/UninstallAction.java Wed Apr 13 18:41:23 2016 @@ -24,22 +24,35 @@ public class UninstallAction extends Abs @Override public Object run() { - checkValid(); - checkRoot(); - State state = target.getState(); - if (EnumSet.of(State.UNINSTALLED).contains(state)) + // Protect against re-entry now that cycles are supported. + if (!LockingStrategy.set(State.STOPPING, target)) { return null; - else if ((State.INSTALLING.equals(state) && Utils.isProvisionDependenciesInstall(target)) - || EnumSet.of(State.RESOLVING, State.STARTING, State.STOPPING, State.UNINSTALLING).contains(state)) { - waitForStateChange(state); - target.uninstall(); } - else if (state.equals(State.ACTIVE)) { - new StopAction(requestor, target, disableRootCheck).run(); - target.uninstall(); + try { + // Acquire the global write lock to prevent all other operations until + // the installation is complete. There is no need to hold any other locks. + LockingStrategy.writeLock(); + try { + checkRoot(); + checkValid(); + State state = target.getState(); + if (EnumSet.of(State.UNINSTALLED).contains(state)) { + return null; + } + if (state.equals(State.ACTIVE)) { + new StopAction(requestor, target, disableRootCheck).run(); + } + ResourceUninstaller.newInstance(requestor, target).uninstall(); + } + finally { + // Release the global write lock. + LockingStrategy.writeUnlock(); + } + } + finally { + // Protection against re-entry no longer required. + LockingStrategy.unset(State.STOPPING, target); } - else - ResourceUninstaller.newInstance(requestor, target).uninstall(); return null; } } Modified: aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/WovenClassListener.java URL: http://svn.apache.org/viewvc/aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/WovenClassListener.java?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/WovenClassListener.java (original) +++ aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/WovenClassListener.java Wed Apr 13 18:41:23 2016 @@ -19,20 +19,20 @@ package org.apache.aries.subsystem.core.internal; import java.security.AccessController; -import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; -import java.util.Deque; import java.util.EnumSet; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.concurrent.atomic.AtomicBoolean; +import java.util.Set; import org.apache.aries.subsystem.core.archive.DynamicImportPackageHeader; import org.apache.aries.subsystem.core.archive.DynamicImportPackageRequirement; import org.apache.aries.subsystem.core.internal.BundleResourceInstaller.BundleConstituent; +import org.apache.aries.subsystem.core.internal.StartAction.Restriction; import org.eclipse.equinox.region.Region; +import org.eclipse.equinox.region.RegionDigraph.FilteredRegion; import org.eclipse.equinox.region.RegionDigraphVisitor; import org.eclipse.equinox.region.RegionFilter; import org.osgi.framework.Bundle; @@ -112,7 +112,7 @@ public class WovenClassListener implemen // package imports to the sharing policy in order to minimize // unpredictable wirings. Resolving the scoped subsystem will also // resolve all of the unscoped subsystems in the region. - AccessController.doPrivileged(new StartAction(subsystem, subsystem, subsystem, true)); + AccessController.doPrivileged(new StartAction(subsystem, subsystem, subsystem, Restriction.RESOLVE_ONLY)); } Bundle systemBundle = context.getBundle(org.osgi.framework.Constants.SYSTEM_BUNDLE_LOCATION); FrameworkWiring frameworkWiring = systemBundle.adapt(FrameworkWiring.class); @@ -162,84 +162,61 @@ public class WovenClassListener implemen final Map<Region, BasicSubsystem> regionToSubsystem = new HashMap<Region, BasicSubsystem>(); regionToSubsystem(scopedSubsystem, regionToSubsystem); scopedSubsystem.getRegion().visitSubgraph(new RegionDigraphVisitor() { - private final AtomicBoolean abort = new AtomicBoolean(); - private final Deque<BasicSubsystem> deque = new ArrayDeque<BasicSubsystem>(); + private final List<BasicSubsystem> visited = new ArrayList<BasicSubsystem>(); @Override public void postEdgeTraverse(RegionFilter filter) { - if ( // The queue will be empty if the necessary sharing - // policy updates have already been detected. - deque.isEmpty() || - // This is an edge whose head region was owned by a - // subsystem that was not a parent of the last processed - // subsystem. - abort.getAndSet(false)) { - // Do nothing. - return; - } - BasicSubsystem subsystem = deque.pop(); - if (filter.isAllowed(providers.iterator().next())) { - // The sharing policy already allows the dynamic import - // so no update is necessary. - return; - } - // Add the subsystem to the list indicating a sharing policy - // update is required. - subsystems.add(subsystem); + // Nothing. } @Override public boolean preEdgeTraverse(RegionFilter filter) { - if (deque.isEmpty()) { - // The queue will be empty if the necessary sharing policy - // updates have already been detected. - // Do not visit the head region of this filter connection. - return false; - } - // Visit the head region of this filter connection return true; } @Override public boolean visit(Region region) { BasicSubsystem subsystem = regionToSubsystem.get(region); - if (subsystem == null) { - // Neither the subsystem whose subgraph is being visited nor - // any ancestor in the subsystem tree owns this region. + if (subsystem == null || subsystem.isRoot()) { + // Don't mess with regions not created by the subsystem + // implementation. Also, the root subsystem never has a + // sharing policy. return false; } - if ( // The deque will be empty if this is first region visited. - !deque.isEmpty() && - // This region is not owned by the scoped subsystem in - // the parent region of the last processed subsystem. - // We want to traverse up the tree. - !scopedParent(deque.getFirst()).equals(subsystem)) { - // Indicate to postEdgeTraverse that it should not add a - // subsystem to the list. - abort.set(true); - // Do not traverse the edges of this region. + if (!visited.isEmpty() && !subsystem.equals(scopedParent(visited.get(visited.size() - 1)))) { + // We're only interested in walking up the scoped parent tree. return false; } - // Let postEdgeTraverse see the currently processing subsystem. - deque.push(subsystem); - for (BundleCapability provider : providers) { - BundleRevision br = provider.getResource(); - if (region.contains(br.getBundle()) && !requirement.getPackageName().contains("*")) { - // The subsystem contains the provider so there is no - // need to update it's sharing policy. Remove it from - // the list. - deque.pop(); - // Do not traverse the edges of this region. - return false; + visited.add(subsystem); + if (!requirement.getPackageName().contains("*")) { + for (BundleCapability provider : providers) { + BundleRevision br = provider.getResource(); + if (region.contains(br.getBundle())) { + // The region contains a bundle providing a matching + // capability, and the dynamic import does not contain a + // wildcard. The requirement is therefore completely + // satisfied. + return false; + } + } + } + boolean allowed = false; + Set<FilteredRegion> filters = region.getEdges(); + for (FilteredRegion filteredRegion : filters) { + RegionFilter filter = filteredRegion.getFilter(); + if (filter.isAllowed(providers.iterator().next())) { + // The region already allows matching capabilities + // through so there is no need to update the sharing + // policy. + allowed = true; + break; } } - if (region.getEdges().isEmpty()) { - // We want to traverse the edges but it has none. This means - // there is no sharing policy to update. Remove it from the - // list. - deque.pop(); + if (!allowed) { + // The subsystem region requires a sharing policy update. + subsystems.add(subsystem); } - // Traverse the edges of this region. + // Visit the next region. return true; } }); Modified: aries/branches/java6support/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemTest.java URL: http://svn.apache.org/viewvc/aries/branches/java6support/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemTest.java?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemTest.java (original) +++ aries/branches/java6support/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemTest.java Wed Apr 13 18:41:23 2016 @@ -132,6 +132,7 @@ public abstract class SubsystemTest exte return new Option[] { baseOptions(), systemProperty("org.osgi.framework.bsnversion").value("multiple"), + systemProperty("org.osgi.framework.storage.clean").value("onFirstInit"), // Bundles mavenBundle("org.apache.aries", "org.apache.aries.util").versionAsInProject(), mavenBundle("org.apache.aries.application", "org.apache.aries.application.utils").versionAsInProject(), @@ -193,26 +194,48 @@ public abstract class SubsystemTest exte @SuppressWarnings("rawtypes") protected Collection<ServiceRegistration> serviceRegistrations = new ArrayList<ServiceRegistration>(); + protected final List<Region> deletableRegions = Collections.synchronizedList(new ArrayList<Region>()); + protected final List<Subsystem> stoppableSubsystems = Collections.synchronizedList(new ArrayList<Subsystem>()); + protected final List<Bundle> uninstallableBundles = Collections.synchronizedList(new ArrayList<Bundle>()); + protected final List<Subsystem> uninstallableSubsystems = Collections.synchronizedList(new ArrayList<Subsystem>()); + @Before public void setUp() throws Exception { + serviceRegistrations.clear(); + deletableRegions.clear(); + stoppableSubsystems.clear(); + uninstallableBundles.clear(); + uninstallableSubsystems.clear(); if (!createdApplications) { createApplications(); createdApplications = true; } bundleContext.getBundle(0).getBundleContext().addServiceListener(subsystemEvents, '(' + Constants.OBJECTCLASS + '=' + Subsystem.class.getName() + ')'); } - - protected void createApplications() throws Exception { - } - + @SuppressWarnings("rawtypes") @After public void tearDown() throws Exception { + for (Subsystem subsystem : stoppableSubsystems) { + stopSubsystemSilently(subsystem); + } + for (Subsystem subsystem : uninstallableSubsystems) { + uninstallSubsystemSilently(subsystem); + } + RegionDigraph digraph = context().getService(RegionDigraph.class); + for (Region region : deletableRegions) { + digraph.removeRegion(region); + } + for (Bundle bundle : uninstallableBundles) { + uninstallSilently(bundle); + } bundleContext.removeServiceListener(subsystemEvents); for (ServiceRegistration registration : serviceRegistrations) Utils.unregisterQuietly(registration); - serviceRegistrations.clear(); + } + + protected void createApplications() throws Exception { } protected RichBundleContext context(Subsystem subsystem) { @@ -976,7 +999,9 @@ public abstract class SubsystemTest exte try { bundle.uninstall(); } - catch (Exception e) {} + catch (Exception e) { + e.printStackTrace(); + } } protected void uninstallSubsystem(Subsystem subsystem) throws Exception { Modified: aries/branches/java6support/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/defect/Aries1383Test.java URL: http://svn.apache.org/viewvc/aries/branches/java6support/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/defect/Aries1383Test.java?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/defect/Aries1383Test.java (original) +++ aries/branches/java6support/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/defect/Aries1383Test.java Wed Apr 13 18:41:23 2016 @@ -9,7 +9,6 @@ import static org.junit.Assert.fail; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.EnumSet; @@ -37,6 +36,7 @@ import org.easymock.internal.matchers.Nu import org.junit.Test; import org.ops4j.pax.tinybundles.core.InnerClassStrategy; import org.ops4j.pax.tinybundles.core.TinyBundles; +import org.osgi.framework.Bundle; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; @@ -95,9 +95,6 @@ public class Aries1383Test extends Subsy private static final String PACKAGE_D = SYMBOLICNAME_PREFIX + "d"; private static final String SUBSYSTEM_MANIFEST_FILE = "OSGI-INF/SUBSYSTEM.MF"; - private final List<Subsystem> stoppableSubsystems = new ArrayList<Subsystem>(); - private final List<Subsystem> uninstallableSubsystems = new ArrayList<Subsystem>(); - /* * (1) A set of subsystems with interleaving content dependencies are able * to be independently, simultaneously, and successfully installed and @@ -124,7 +121,7 @@ public class Aries1383Test extends Subsy new Callable<Subsystem>() { @Override public Subsystem call() throws Exception { - return installSubsystem( + Subsystem result = installSubsystem( c1, "a1", new SubsystemArchiveBuilder() @@ -140,13 +137,15 @@ public class Aries1383Test extends Subsy .build()) .build(), false); + uninstallableSubsystems.add(result); + return result; } }, new Callable<Subsystem>() { @Override public Subsystem call() throws Exception { - return installSubsystem( + Subsystem result = installSubsystem( c1, "f1", new SubsystemArchiveBuilder() @@ -163,13 +162,15 @@ public class Aries1383Test extends Subsy .build()) .build(), false); + uninstallableSubsystems.add(result); + return result; } }, new Callable<Subsystem>() { @Override public Subsystem call() throws Exception { - return installSubsystem( + Subsystem result = installSubsystem( c1, "f2", new SubsystemArchiveBuilder() @@ -187,13 +188,15 @@ public class Aries1383Test extends Subsy .build()) .build(), false); + uninstallableSubsystems.add(result); + return result; } }, new Callable<Subsystem>() { @Override public Subsystem call() throws Exception { - return installSubsystem( + Subsystem result = installSubsystem( c1, "c2", new SubsystemArchiveBuilder() @@ -212,6 +215,8 @@ public class Aries1383Test extends Subsy .build()) .build(), false); + uninstallableSubsystems.add(result); + return result; } } @@ -219,16 +224,12 @@ public class Aries1383Test extends Subsy ExecutorService executor = Executors.newFixedThreadPool(4); List<Future<Subsystem>> installFutures = executor.invokeAll(Arrays.asList(installCallables)); final Subsystem a1 = installFutures.get(0).get(); - uninstallableSubsystems.add(a1); assertConstituent(a1, "b1"); final Subsystem f1 = installFutures.get(1).get(); - uninstallableSubsystems.add(f1); assertConstituent(f1, "b2"); final Subsystem f2 = installFutures.get(2).get(); - uninstallableSubsystems.add(f2); assertConstituent(f2, "b4"); final Subsystem c2 = installFutures.get(3).get(); - uninstallableSubsystems.add(c2); assertConstituent(c2, "b3"); @SuppressWarnings("unchecked") Callable<Null>[] startCallables = new Callable[] { @@ -239,6 +240,7 @@ public class Aries1383Test extends Subsy assertEvent(a1, State.INSTALLED, subsystemEvents.poll(a1.getSubsystemId(), 5000)); assertEvent(a1, State.RESOLVING, subsystemEvents.poll(a1.getSubsystemId(), 5000)); assertEvent(a1, State.RESOLVED, subsystemEvents.poll(a1.getSubsystemId(), 5000)); + stoppableSubsystems.add(a1); return null; } }, @@ -249,6 +251,7 @@ public class Aries1383Test extends Subsy assertEvent(f1, State.INSTALLED, subsystemEvents.poll(f1.getSubsystemId(), 5000)); assertEvent(f1, State.RESOLVING, subsystemEvents.poll(f1.getSubsystemId(), 5000)); assertEvent(f1, State.RESOLVED, subsystemEvents.poll(f1.getSubsystemId(), 5000)); + stoppableSubsystems.add(f1); return null; } }, @@ -259,6 +262,7 @@ public class Aries1383Test extends Subsy assertEvent(f2, State.INSTALLED, subsystemEvents.poll(f2.getSubsystemId(), 5000)); assertEvent(f2, State.RESOLVING, subsystemEvents.poll(f2.getSubsystemId(), 5000)); assertEvent(f2, State.RESOLVED, subsystemEvents.poll(f2.getSubsystemId(), 5000)); + stoppableSubsystems.add(f2); return null; } }, @@ -269,19 +273,16 @@ public class Aries1383Test extends Subsy assertEvent(c2, State.INSTALLED, subsystemEvents.poll(c2.getSubsystemId(), 5000)); assertEvent(c2, State.RESOLVING, subsystemEvents.poll(c2.getSubsystemId(), 5000)); assertEvent(c2, State.RESOLVED, subsystemEvents.poll(c2.getSubsystemId(), 5000)); + stoppableSubsystems.add(c2); return null; } } }; List<Future<Null>> startFutures = executor.invokeAll(Arrays.asList(startCallables)); startFutures.get(0).get(); - stoppableSubsystems.add(a1); startFutures.get(1).get(); - stoppableSubsystems.add(f1); startFutures.get(2).get(); - stoppableSubsystems.add(f2); startFutures.get(3).get(); - stoppableSubsystems.add(c2); } /* @@ -1442,7 +1443,7 @@ public class Aries1383Test extends Subsy assertConstituent(f1, "b2"); startSubsystem(f1, false); stoppableSubsystems.add(f1); - assertState(State.RESOLVED, f2); + assertState(EnumSet.of(State.RESOLVED, State.ACTIVE), f2); assertConstituent(s1, "b4"); assertConstituent(s1, "b5"); assertConstituent(s1, "b6"); @@ -1816,35 +1817,64 @@ public class Aries1383Test extends Subsy .build(); } - private static class BundleStartFailureActivator implements BundleActivator { + public static interface TestService {} + + public static class TestServiceImpl implements TestService {} + + public static class TestServiceClientActivator implements BundleActivator { @Override public void start(BundleContext context) throws Exception { - throw new IllegalStateException(); + ServiceReference<TestService> ref = null; + for (int i = 0; i < 80; i++) { // 20 seconds with 250ms sleep. + ref = context.getServiceReference(TestService.class); + if (ref == null) { + Thread.sleep(250); + continue; + } + break; + } + try { + TestService service = context.getService(ref); + service.getClass(); + } + finally { + context.ungetService(ref); + } } @Override public void stop(BundleContext context) throws Exception { - // Nothing. } } - @Override - public void setUp() throws Exception { - super.setUp(); - stoppableSubsystems.clear(); - uninstallableSubsystems.clear(); - } - - @Override - public void tearDown() throws Exception { - for (Subsystem subsystem : stoppableSubsystems) { - stopSubsystemSilently(subsystem); + public static class TestServiceImplActivator implements BundleActivator { + private ServiceRegistration<TestService> reg; + + @Override + public void start(BundleContext context) throws Exception { + reg = context.registerService( + TestService.class, + new TestServiceImpl(), + null); } - for (Subsystem subsystem : uninstallableSubsystems) { - uninstallSubsystemSilently(subsystem); + + @Override + public void stop(BundleContext context) throws Exception { + reg.unregister(); + } + } + + private static class BundleStartFailureActivator implements BundleActivator { + @Override + public void start(BundleContext context) throws Exception { + throw new IllegalStateException(); + } + + @Override + public void stop(BundleContext context) throws Exception { + // Nothing. } - super.tearDown(); - } + } @Test public void testInterleavingContentDependencies() throws Exception { @@ -1896,6 +1926,7 @@ public class Aries1383Test extends Subsy startSubsystem(c1, false); stoppableSubsystems.add(c1); assertState(EnumSet.of(State.RESOLVED, State.ACTIVE), c2); + stoppableSubsystems.add(c2); } @Test @@ -1922,6 +1953,7 @@ public class Aries1383Test extends Subsy .build(), false ); + uninstallableSubsystems.add(c1); Subsystem c2 = installSubsystem( root, "c2", @@ -1943,6 +1975,7 @@ public class Aries1383Test extends Subsy .build(), false ); + uninstallableSubsystems.add(c2); assertChild(root, "c1", null, SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE); assertChild(root, "c2", null, SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE); restartSubsystemsImplBundle(); @@ -2141,4 +2174,546 @@ public class Aries1383Test extends Subsy e.printStackTrace(); } } + + @Test + public void testMatchingCapabilityInDisconnectedRegion() throws Exception { + Subsystem root = getRootSubsystem(); + BundleArchiveBuilder b1Builder = new BundleArchiveBuilder() + .symbolicName("b1") + .exportPackage("b1"); + Bundle b1 = root.getBundleContext().installBundle("b1", b1Builder.build()); + try { + Subsystem a1 = installSubsystem( + root, + "a1", + new SubsystemArchiveBuilder() + .symbolicName("a1") + .type(SubsystemConstants.SUBSYSTEM_TYPE_APPLICATION + + ';' + + AriesProvisionDependenciesDirective.RESOLVE.toString() + + ';' + + SubsystemConstants.PROVISION_POLICY_DIRECTIVE + + ":=" + + SubsystemConstants.PROVISION_POLICY_ACCEPT_DEPENDENCIES) + .build(), + false + ); + uninstallableSubsystems.add(a1); + startSubsystem(a1, false); + stoppableSubsystems.add(a1); + removeConnectionWithParent(a1); + Subsystem a2 = installSubsystem( + a1, + "a2", + new SubsystemArchiveBuilder() + .symbolicName("a2") + .type(SubsystemConstants.SUBSYSTEM_TYPE_APPLICATION) + .content("b2") + .bundle( + "b2", + new BundleArchiveBuilder() + .symbolicName("b2") + .importPackage("b1") + .build()) + .bundle( + "b1", + b1Builder.build()) + .build(), + false + ); + uninstallableSubsystems.add(a2); + assertState(State.INSTALLING, a2); + assertNotConstituent(a1, "b1"); + try { + startSubsystem(a2, false); + stoppableSubsystems.add(a2); + assertConstituent(a1, "b1"); + } + catch (SubsystemException e) { + e.printStackTrace(); + fail("Subsystem should have started"); + } + } + finally { + uninstallSilently(b1); + } + } + + @Test + public void testProvideCapabilityNamespaceOnly() throws Exception { + Subsystem root = getRootSubsystem(); + Subsystem c1 = installSubsystem( + root, + "c1", + new SubsystemArchiveBuilder() + .symbolicName("c1") + .type(SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE) + .provideCapability("y") + .build()); + uninstallableSubsystems.add(c1); + try { + startSubsystem(c1); + stoppableSubsystems.add(c1); + } + catch (SubsystemException e) { + e.printStackTrace(); + fail("Subsystem should have started"); + } + } + + @Test + public void testComApiComImplAppClient() throws Exception { + Subsystem root = getRootSubsystem(); + final Subsystem shared = installSubsystem( + root, + "shared", + new SubsystemArchiveBuilder() + .symbolicName("shared") + .type(SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE + + ';' + + AriesProvisionDependenciesDirective.RESOLVE.toString() + + ';' + + SubsystemConstants.PROVISION_POLICY_DIRECTIVE + + ":=" + + SubsystemConstants.PROVISION_POLICY_ACCEPT_DEPENDENCIES) + .importPackage("org.osgi.framework") + .build(), + false + ); + uninstallableSubsystems.add(shared); + shared.start(); + stoppableSubsystems.add(shared); + @SuppressWarnings("unchecked") + Callable<Subsystem>[] installCallables = new Callable[] { + new Callable<Subsystem>() { + @Override + public Subsystem call() throws Exception { + Subsystem result = installSubsystem( + shared, + "client", + new SubsystemArchiveBuilder() + .symbolicName("client") + .type(SubsystemConstants.SUBSYSTEM_TYPE_APPLICATION) + .bundle( + "client", + new BundleArchiveBuilder() + .symbolicName("client") + .importPackage("org.apache.aries.subsystem.itests.defect") + .requireCapability("osgi.service;filter:=\"(objectClass=" + + TestService.class.getName() + + ")\";effective:=active") + .build()) + .build(), + false); + uninstallableSubsystems.add(result); + return result; + } + + }, + new Callable<Subsystem>() { + @Override + public Subsystem call() throws Exception { + Subsystem result = installSubsystem( + shared, + "impl", + new SubsystemArchiveBuilder() + .symbolicName("impl") + .type(SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE) + .content("impl;version=\"[0,0]\"") + .provideCapability("osgi.service;objectClass:List<String>=\"" + + TestService.class.getName() + + "\"") + .importPackage("org.osgi.framework") + .requireBundle("api") + .bundle( + "impl", + new BundleArchiveBuilder() + .symbolicName("impl") + .provideCapability("osgi.service;objectClass:List<String>=\"" + + TestService.class.getName() + + "\"") + .importPackage("org.osgi.framework") + .requireBundle("api") + .clazz(TestServiceImpl.class) + .activator(TestServiceImplActivator.class) + .build()) + .build(), + false); + uninstallableSubsystems.add(result); + return result; + } + + }, + new Callable<Subsystem>() { + @Override + public Subsystem call() throws Exception { + Subsystem result = installSubsystem( + shared, + "api", + new SubsystemArchiveBuilder() + .symbolicName("api") + .type(SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE) + .content("api;version=\"[0,0]\"") + .exportPackage("org.apache.aries.subsystem.itests.defect") + .provideCapability("osgi.wiring.bundle;osgi.wiring.bundle=api;bundle-version=0") + .bundle( + "api", + new BundleArchiveBuilder() + .symbolicName("api") + .exportPackage("org.apache.aries.subsystem.itests.defect") + .clazz(TestService.class) + .build()) + .build(), + false); + uninstallableSubsystems.add(result); + return result; + } + + } + }; + ExecutorService executor = Executors.newFixedThreadPool(3); + List<Future<Subsystem>> installFutures = executor.invokeAll(Arrays.asList(installCallables)); + final Subsystem a1 = installFutures.get(0).get(); + final Subsystem c1 = installFutures.get(1).get(); + final Subsystem c2 = installFutures.get(2).get(); + @SuppressWarnings("unchecked") + Callable<Void>[] startCallables = new Callable[] { + new Callable<Void>() { + @Override + public Void call() throws Exception { + a1.start(); + stoppableSubsystems.add(a1); + assertEvent(a1, State.INSTALLED, subsystemEvents.poll(a1.getSubsystemId(), 5000)); + assertEvent(a1, State.RESOLVING, subsystemEvents.poll(a1.getSubsystemId(), 5000)); + assertEvent(a1, State.RESOLVED, subsystemEvents.poll(a1.getSubsystemId(), 5000)); + assertEvent(a1, State.STARTING, subsystemEvents.poll(a1.getSubsystemId(), 5000)); + assertEvent(a1, State.ACTIVE, subsystemEvents.poll(a1.getSubsystemId(), 5000)); + return null; + } + }, + new Callable<Void>() { + @Override + public Void call() throws Exception { + c1.start(); + stoppableSubsystems.add(c1); + assertEvent(c1, State.INSTALLED, subsystemEvents.poll(c1.getSubsystemId(), 5000)); + assertEvent(c1, State.RESOLVING, subsystemEvents.poll(c1.getSubsystemId(), 5000)); + assertEvent(c1, State.RESOLVED, subsystemEvents.poll(c1.getSubsystemId(), 5000)); + assertEvent(c1, State.STARTING, subsystemEvents.poll(c1.getSubsystemId(), 5000)); + assertEvent(c1, State.ACTIVE, subsystemEvents.poll(c1.getSubsystemId(), 5000)); + return null; + } + }, + new Callable<Void>() { + @Override + public Void call() throws Exception { + c2.start(); + stoppableSubsystems.add(c2); + assertEvent(c2, State.INSTALLED, subsystemEvents.poll(c2.getSubsystemId(), 5000)); + assertEvent(c2, State.RESOLVING, subsystemEvents.poll(c2.getSubsystemId(), 5000)); + assertEvent(c2, State.RESOLVED, subsystemEvents.poll(c2.getSubsystemId(), 5000)); + assertEvent(c2, State.STARTING, subsystemEvents.poll(c2.getSubsystemId(), 5000)); + assertEvent(c2, State.ACTIVE, subsystemEvents.poll(c2.getSubsystemId(), 5000)); + return null; + } + } + }; + List<Future<Void>> startFutures = executor.invokeAll(Arrays.asList(startCallables)); + startFutures.get(0).get(); + startFutures.get(1).get(); + startFutures.get(2).get(); + } + + @Test + public void testComApiComImplComClient() throws Exception { + Subsystem root = getRootSubsystem(); + final Subsystem shared = installSubsystem( + root, + "shared", + new SubsystemArchiveBuilder() + .symbolicName("shared") + .type(SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE + + ';' + + AriesProvisionDependenciesDirective.RESOLVE.toString() + + ';' + + SubsystemConstants.PROVISION_POLICY_DIRECTIVE + + ":=" + + SubsystemConstants.PROVISION_POLICY_ACCEPT_DEPENDENCIES) + .importPackage("org.osgi.framework") + .build(), + false + ); + uninstallableSubsystems.add(shared); + shared.start(); + stoppableSubsystems.add(shared); + @SuppressWarnings("unchecked") + Callable<Subsystem>[] installCallables = new Callable[] { + new Callable<Subsystem>() { + @Override + public Subsystem call() throws Exception { + Subsystem result = installSubsystem( + shared, + "client", + new SubsystemArchiveBuilder() + .symbolicName("client") + .type(SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE) + .content("client;version=\"[0,0]\"") + .importPackage("org.osgi.framework") + .requireCapability("osgi.service;filter:=\"(objectClass=" + + TestService.class.getName() + + ")\";effective:=active") + .importService(TestService.class.getName()) + .requireBundle("api,impl") + .bundle( + "client", + new BundleArchiveBuilder() + .symbolicName("client") + .importPackage("org.osgi.framework") + .requireCapability("osgi.service;filter:=\"(objectClass=" + + TestService.class.getName() + + ")\";effective:=active") + .requireBundle("api,impl") + .activator(TestServiceClientActivator.class) + .build()) + .build(), + false); + return result; + } + + }, + new Callable<Subsystem>() { + @Override + public Subsystem call() throws Exception { + Subsystem result = installSubsystem( + shared, + "impl", + new SubsystemArchiveBuilder() + .symbolicName("impl") + .type(SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE) + .content("impl;version=\"[0,0]\"") + .provideCapability("osgi.service;objectClass:List<String>=\"" + + TestService.class.getName() + + "\"") + .exportService(TestService.class.getName()) + .importPackage("org.osgi.framework") + .requireBundle("api") + .provideCapability("osgi.wiring.bundle;osgi.wiring.bundle=impl;bundle-version=0") + .bundle( + "impl", + new BundleArchiveBuilder() + .symbolicName("impl") + .provideCapability("osgi.service;objectClass:List<String>=\"" + + TestService.class.getName() + + "\"") + .importPackage("org.osgi.framework") + .requireBundle("api") + .clazz(TestServiceImpl.class) + .activator(TestServiceImplActivator.class) + .build()) + .build(), + false); + return result; + } + + }, + new Callable<Subsystem>() { + @Override + public Subsystem call() throws Exception { + Subsystem result = installSubsystem( + shared, + "api", + new SubsystemArchiveBuilder() + .symbolicName("api") + .type(SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE) + .content("api;version=\"[0,0]\"") + .exportPackage("org.apache.aries.subsystem.itests.defect") + .provideCapability("osgi.wiring.bundle;osgi.wiring.bundle=api;bundle-version=0") + .bundle( + "api", + new BundleArchiveBuilder() + .symbolicName("api") + .exportPackage("org.apache.aries.subsystem.itests.defect") + .clazz(TestService.class) + .build()) + .build(), + false); + return result; + } + + } + }; + ExecutorService executor = Executors.newFixedThreadPool(3); + List<Future<Subsystem>> installFutures = executor.invokeAll(Arrays.asList(installCallables)); + final Subsystem client = installFutures.get(0).get(); + final Subsystem impl = installFutures.get(1).get(); + final Subsystem api = installFutures.get(2).get(); + @SuppressWarnings("unchecked") + Callable<Void>[] startCallables = new Callable[] { + new Callable<Void>() { + @Override + public Void call() throws Exception { + client.start(); + assertEvent(client, State.INSTALLED, subsystemEvents.poll(client.getSubsystemId(), 5000)); + assertEvent(client, State.RESOLVING, subsystemEvents.poll(client.getSubsystemId(), 5000)); + assertEvent(client, State.RESOLVED, subsystemEvents.poll(client.getSubsystemId(), 5000)); + assertEvent(client, State.STARTING, subsystemEvents.poll(client.getSubsystemId(), 5000)); + assertEvent(client, State.ACTIVE, subsystemEvents.poll(client.getSubsystemId(), 5000)); + return null; + } + }, + new Callable<Void>() { + @Override + public Void call() throws Exception { + impl.start(); + assertEvent(impl, State.INSTALLED, subsystemEvents.poll(impl.getSubsystemId(), 5000)); + assertEvent(impl, State.RESOLVING, subsystemEvents.poll(impl.getSubsystemId(), 5000)); + assertEvent(impl, State.RESOLVED, subsystemEvents.poll(impl.getSubsystemId(), 5000)); + assertEvent(impl, State.STARTING, subsystemEvents.poll(impl.getSubsystemId(), 5000)); + assertEvent(impl, State.ACTIVE, subsystemEvents.poll(impl.getSubsystemId(), 5000)); + return null; + } + }, + new Callable<Void>() { + @Override + public Void call() throws Exception { + api.start(); + assertEvent(api, State.INSTALLED, subsystemEvents.poll(api.getSubsystemId(), 5000)); + assertEvent(api, State.RESOLVING, subsystemEvents.poll(api.getSubsystemId(), 5000)); + assertEvent(api, State.RESOLVED, subsystemEvents.poll(api.getSubsystemId(), 5000)); + assertEvent(api, State.STARTING, subsystemEvents.poll(api.getSubsystemId(), 5000)); + assertEvent(api, State.ACTIVE, subsystemEvents.poll(api.getSubsystemId(), 5000)); + return null; + } + } + }; + List<Future<Void>> startFutures = executor.invokeAll(Arrays.asList(startCallables)); + startFutures.get(0).get(); + startFutures.get(1).get(); + startFutures.get(2).get(); + } + + @Test + public void testAutoInstallDependenciesComposite() throws Exception { + Subsystem root = getRootSubsystem(); + Subsystem b = installSubsystem( + root, + "b", + new SubsystemArchiveBuilder() + .symbolicName("b") + .type(SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE + + ';' + + AriesProvisionDependenciesDirective.RESOLVE.toString()) + .content("a;version=\"[0,0]\"") + .exportPackage("a") + .importPackage("b") + .bundle( + "a", + new BundleArchiveBuilder() + .symbolicName("a") + .importPackage("b") + .exportPackage("a") + .build()) + .bundle( + "b", + new BundleArchiveBuilder() + .symbolicName("b") + .exportPackage("b") + .build()) + .build(), + false + ); + uninstallableSubsystems.add(b); + try { + Subsystem a = installSubsystem( + root, + "a", + new SubsystemArchiveBuilder() + .symbolicName("a") + .type(SubsystemConstants.SUBSYSTEM_TYPE_APPLICATION) + .bundle( + "a", + new BundleArchiveBuilder() + .symbolicName("a") + .importPackage("a") + .build()) + .build(), + true + ); + uninstallableSubsystems.add(a); + assertState(EnumSet.of(State.INSTALLED, State.RESOLVED), b); + } + catch (Exception e) { + e.printStackTrace(); + fail("Subsystem should have installed"); + } + } + + @Test + public void testAutoInstallDependenciesFeature() throws Exception { + Subsystem root = getRootSubsystem(); + Subsystem shared = installSubsystem( + root, + "shared", + new SubsystemArchiveBuilder() + .symbolicName("shared") + .type(SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE + + ';' + + AriesProvisionDependenciesDirective.RESOLVE.toString() + + ';' + + SubsystemConstants.PROVISION_POLICY_DIRECTIVE + + ":=" + + SubsystemConstants.PROVISION_POLICY_ACCEPT_DEPENDENCIES) + .build(), + false + ); + uninstallableSubsystems.add(shared); + startSubsystem(shared, false); + Subsystem b = installSubsystem( + shared, + "b", + new SubsystemArchiveBuilder() + .symbolicName("b") + .type(SubsystemConstants.SUBSYSTEM_TYPE_FEATURE) + .content("a") + .bundle( + "a", + new BundleArchiveBuilder() + .symbolicName("a") + .importPackage("b") + .exportPackage("a") + .build()) + .bundle( + "b", + new BundleArchiveBuilder() + .symbolicName("b") + .exportPackage("b") + .build()) + .build(), + false + ); + try { + installSubsystem( + shared, + "a", + new SubsystemArchiveBuilder() + .symbolicName("a") + .type(SubsystemConstants.SUBSYSTEM_TYPE_APPLICATION + + ';' + + AriesProvisionDependenciesDirective.INSTALL.toString()) + .bundle( + "a", + new BundleArchiveBuilder() + .symbolicName("a") + .importPackage("a") + .build()) + .build(), + true + ); + assertState(EnumSet.of(State.INSTALLED, State.RESOLVED), b); + } + catch (Exception e) { + e.printStackTrace(); + fail("Subsystem should have installed"); + } + } } Modified: aries/branches/java6support/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/defect/Aries1435Test.java URL: http://svn.apache.org/viewvc/aries/branches/java6support/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/defect/Aries1435Test.java?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/defect/Aries1435Test.java (original) +++ aries/branches/java6support/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/defect/Aries1435Test.java Wed Apr 13 18:41:23 2016 @@ -42,6 +42,7 @@ import org.apache.aries.subsystem.itests import org.apache.aries.subsystem.itests.util.TestRepository; import org.apache.aries.subsystem.itests.util.TestRepositoryContent; import org.eclipse.equinox.region.Region; +import org.eclipse.equinox.region.RegionDigraph; import org.eclipse.equinox.region.RegionDigraph.FilteredRegion; import org.eclipse.equinox.region.RegionFilter; import org.junit.Before; @@ -222,7 +223,7 @@ public class Aries1435Test extends Subsy } } finally { - bundleB.uninstall(); + uninstallSilently(bundleB); } } @@ -307,7 +308,7 @@ public class Aries1435Test extends Subsy uninstallSubsystemSilently(applicationB); } finally { - bundleB.uninstall(); + uninstallSilently(bundleB); } } finally { @@ -343,7 +344,7 @@ public class Aries1435Test extends Subsy testSharingPolicy(getRootSubsystem(), "b.a", false); } finally { - bundleB.uninstall(); + uninstallSilently(bundleB); } } finally { @@ -785,4 +786,41 @@ public class Aries1435Test extends Subsy fail("Sharing policy should have been updated"); } } + + @Test + public void testConnectedNonSubsystemRegions() throws Exception { + registerWeavingHook("b"); + Bundle bundleB = getRootSubsystem().getBundleContext().installBundle( + BUNDLE_B, new ByteArrayInputStream(createBundleBContent())); + uninstallableBundles.add(bundleB); + Subsystem applicationA = installSubsystemFromFile(APPLICATION_A); + uninstallableSubsystems.add(applicationA); + Subsystem applicationB = getChild(applicationA, APPLICATION_B); + uninstallSubsystem(applicationB); + removeConnectionWithParent(applicationA); + Region region = getRegion(applicationA); + RegionDigraph digraph = region.getRegionDigraph(); + Region r1 = digraph.createRegion("R1"); + deletableRegions.add(r1); + region.connectRegion(r1, digraph.createRegionFilterBuilder().allow("y", "(y=x)").build()); + Region r2a = digraph.createRegion("R2A"); + deletableRegions.add(r2a); + Bundle bundleB1 = r2a.installBundleAtLocation(BUNDLE_B + '1', new ByteArrayInputStream(createBundleBContent())); + uninstallableBundles.add(bundleB1); + Region r2b = digraph.createRegion("R2B"); + deletableRegions.add(r2b); + r2b.connectRegion(r2a, digraph.createRegionFilterBuilder().allow("osgi.wiring.package", "(&(osgi.wiring.package=b)(version=0))").build()); + region.connectRegion(r2b, digraph.createRegionFilterBuilder().allow("osgi.wiring.package", "(&(osgi.wiring.package=b)(version=0))").build()); + applicationB = installSubsystemFromFile(applicationA, APPLICATION_B); + uninstallableSubsystems.add(applicationB); + try { + testDynamicImport(applicationB, "b.B"); + } + catch (AssertionError e) { + fail("Dynamic import should have succeeded"); + } + testSharingPolicy(applicationB, "b", true); + testSharingPolicy(applicationA, "b", true); + testSharingPolicy(getRootSubsystem(), "b", false); + } } Modified: aries/branches/java6support/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/util/BundleArchiveBuilder.java URL: http://svn.apache.org/viewvc/aries/branches/java6support/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/util/BundleArchiveBuilder.java?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/util/BundleArchiveBuilder.java (original) +++ aries/branches/java6support/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/util/BundleArchiveBuilder.java Wed Apr 13 18:41:23 2016 @@ -4,6 +4,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import org.ops4j.pax.tinybundles.core.InnerClassStrategy; import org.ops4j.pax.tinybundles.core.TinyBundle; import org.ops4j.pax.tinybundles.core.TinyBundles; @@ -18,6 +19,12 @@ public class BundleArchiveBuilder { bundle = TinyBundles.bundle(); } + public BundleArchiveBuilder activator(Class<?> clazz) { + bundle.set(Constants.BUNDLE_ACTIVATOR, clazz.getName()); + bundle.add(clazz, InnerClassStrategy.NONE); + return this; + } + public InputStream build() { return bundle.build(); } @@ -35,6 +42,11 @@ public class BundleArchiveBuilder { return baos.toByteArray(); } + public BundleArchiveBuilder clazz(Class<?> clazz) { + bundle.add(clazz, InnerClassStrategy.NONE); + return this; + } + public BundleArchiveBuilder exportPackage(String value) { return header(Constants.EXPORT_PACKAGE, value); } @@ -48,6 +60,18 @@ public class BundleArchiveBuilder { return header(Constants.IMPORT_PACKAGE, value); } + public BundleArchiveBuilder provideCapability(String value) { + return header(Constants.PROVIDE_CAPABILITY, value); + } + + public BundleArchiveBuilder requireBundle(String value) { + return header(Constants.REQUIRE_BUNDLE, value); + } + + public BundleArchiveBuilder requireCapability(String value) { + return header(Constants.REQUIRE_CAPABILITY, value); + } + public BundleArchiveBuilder symbolicName(String value) { return header(Constants.BUNDLE_SYMBOLICNAME, value); } Modified: aries/branches/java6support/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/util/SubsystemArchiveBuilder.java URL: http://svn.apache.org/viewvc/aries/branches/java6support/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/util/SubsystemArchiveBuilder.java?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/util/SubsystemArchiveBuilder.java (original) +++ aries/branches/java6support/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/util/SubsystemArchiveBuilder.java Wed Apr 13 18:41:23 2016 @@ -49,6 +49,10 @@ public class SubsystemArchiveBuilder { return header(Constants.EXPORT_PACKAGE, value); } + public SubsystemArchiveBuilder exportService(String value) { + return header(SubsystemConstants.SUBSYSTEM_EXPORTSERVICE, value); + } + public SubsystemArchiveBuilder file(String name, InputStream value) { bundle.add(name, value); return this; @@ -63,6 +67,22 @@ public class SubsystemArchiveBuilder { return header(Constants.IMPORT_PACKAGE, value); } + public SubsystemArchiveBuilder importService(String value) { + return header(SubsystemConstants.SUBSYSTEM_IMPORTSERVICE, value); + } + + public SubsystemArchiveBuilder provideCapability(String value) { + return header(Constants.PROVIDE_CAPABILITY, value); + } + + public SubsystemArchiveBuilder requireBundle(String value) { + return header(Constants.REQUIRE_BUNDLE, value); + } + + public SubsystemArchiveBuilder requireCapability(String value) { + return header(Constants.REQUIRE_CAPABILITY, value); + } + public SubsystemArchiveBuilder subsystem(String name, InputStream value) { return file(name + ESA_EXTENSION, value); } Modified: aries/branches/java6support/transaction/transaction-blueprint/pom.xml URL: http://svn.apache.org/viewvc/aries/branches/java6support/transaction/transaction-blueprint/pom.xml?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/transaction/transaction-blueprint/pom.xml (original) +++ aries/branches/java6support/transaction/transaction-blueprint/pom.xml Wed Apr 13 18:41:23 2016 @@ -31,7 +31,7 @@ <groupId>org.apache.aries.transaction</groupId> <artifactId>org.apache.aries.transaction.blueprint</artifactId> <packaging>bundle</packaging> - <version>2.1.0-SNAPSHOT</version> + <version>2.2.0-SNAPSHOT</version> <name>Apache Aries Transaction Blueprint</name> <scm> Modified: aries/branches/java6support/transaction/transaction-itests/pom.xml URL: http://svn.apache.org/viewvc/aries/branches/java6support/transaction/transaction-itests/pom.xml?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/transaction/transaction-itests/pom.xml (original) +++ aries/branches/java6support/transaction/transaction-itests/pom.xml Wed Apr 13 18:41:23 2016 @@ -133,7 +133,7 @@ <groupId>org.apache.aries.transaction</groupId> <artifactId>org.apache.aries.transaction.blueprint</artifactId> <scope>test</scope> - <version>2.1.0-SNAPSHOT</version> + <version>2.2.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.apache.aries.transaction</groupId>
