Modified: aries/branches/java6support/jpa/itests/jpa-container-itest/src/test/java/org/apache/aries/jpa/itest/AbstractJPAItest.java URL: http://svn.apache.org/viewvc/aries/branches/java6support/jpa/itests/jpa-container-itest/src/test/java/org/apache/aries/jpa/itest/AbstractJPAItest.java?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/jpa/itests/jpa-container-itest/src/test/java/org/apache/aries/jpa/itest/AbstractJPAItest.java (original) +++ aries/branches/java6support/jpa/itests/jpa-container-itest/src/test/java/org/apache/aries/jpa/itest/AbstractJPAItest.java Wed Apr 13 18:41:23 2016 @@ -33,6 +33,7 @@ import javax.transaction.UserTransaction import org.junit.Before; import org.junit.runner.RunWith; +import org.ops4j.pax.exam.CoreOptions; import org.ops4j.pax.exam.Option; import org.ops4j.pax.exam.junit.PaxExam; import org.ops4j.pax.exam.options.MavenArtifactProvisionOption; @@ -182,7 +183,7 @@ public abstract class AbstractJPAItest { .value("javax.accessibility,javax.activation,javax.activity,javax.annotation,javax.annotation.processing,javax.crypto,javax.crypto.interfaces,javax.crypto.spec,javax.imageio,javax.imageio.event,javax.imageio.metadata,javax.imageio.plugins.bmp,javax.imageio.plugins.jpeg,javax.imageio.spi,javax.imageio.stream,javax.jws,javax.jws.soap,javax.lang.model,javax.lang.model.element,javax.lang.model.type,javax.lang.model.util,javax.management,javax.management.loading,javax.management.modelmbean,javax.management.monitor,javax.management.openmbean,javax.management.relation,javax.management.remote,javax.management.remote.rmi,javax.management.timer,javax.naming,javax.naming.directory,javax.naming.event,javax.naming.ldap,javax.naming.spi,javax.net,javax.net.ssl,javax.print,javax.print.attribute,javax.print.attribute.standard,javax.print.event,javax.rmi,javax.rmi.CORBA,javax.rmi.ssl,javax.script,javax.security.auth,javax.security.auth.callback,javax.security.auth.kerberos,j avax.security.auth.login,javax.security.auth.spi,javax.security.auth.x500,javax.security.cert,javax.security.sasl,javax.sound.midi,javax.sound.midi.spi,javax.sound.sampled,javax.sound.sampled.spi,javax.sql,javax.sql.rowset,javax.sql.rowset.serial,javax.sql.rowset.spi,javax.swing,javax.swing.border,javax.swing.colorchooser,javax.swing.event,javax.swing.filechooser,javax.swing.plaf,javax.swing.plaf.basic,javax.swing.plaf.metal,javax.swing.plaf.multi,javax.swing.plaf.synth,javax.swing.table,javax.swing.text,javax.swing.text.html,javax.swing.text.html.parser,javax.swing.text.rtf,javax.swing.tree,javax.swing.undo,javax.tools,javax.xml,javax.xml.bind,javax.xml.bind.annotation,javax.xml.bind.annotation.adapters,javax.xml.bind.attachment,javax.xml.bind.helpers,javax.xml.bind.util,javax.xml.crypto,javax.xml.crypto.dom,javax.xml.crypto.dsig,javax.xml.crypto.dsig.dom,javax.xml.crypto.dsig.keyinfo,javax.xml.crypto.dsig.spec,javax.xml.datatype,javax.xml.namespace,javax.xml.parsers,javax.xml.soap ," + "javax.xml.stream; version=1.0,javax.xml.stream.events; version=1.0,javax.xml.stream.util; version=1.0," + "javax.xml.transform,javax.xml.transform.dom,javax.xml.transform.sax,javax.xml.transform.stax,javax.xml.transform.stream,javax.xml.validation,javax.xml.ws,javax.xml.ws.handler,javax.xml.ws.handler.soap,javax.xml.ws.http,javax.xml.ws.soap,javax.xml.ws.spi,javax.xml.xpath,org.ietf.jgss,org.omg.CORBA,org.omg.CORBA.DynAnyPackage,org.omg.CORBA.ORBPackage,org.omg.CORBA.TypeCodePackage,org.omg.CORBA.portable,org.omg.CORBA_2_3,org.omg.CORBA_2_3.portable,org.omg.CosNaming,org.omg.CosNaming.NamingContextExtPackage,org.omg.CosNaming.NamingContextPackage,org.omg.Dynamic,org.omg.DynamicAny,org.omg.DynamicAny.DynAnyFactoryPackage,org.omg.DynamicAny.DynAnyPackage,org.omg.IOP,org.omg.IOP.CodecFactoryPackage,org.omg.IOP.CodecPackage,org.omg.Messaging,org.omg.PortableInterceptor,org.omg.PortableInterceptor.ORBInitInfoPackage,org.omg.PortableServer,org.omg.PortableServer.CurrentPackage,org.omg.PortableServer.POAManagerPackage,org.omg.PortableServer.POAPackage,org.omg.Por tableServer.ServantLocatorPackage,org.omg.PortableServer.portable,org.omg.SendingContext,org.omg.stub.java.rmi,org.w3c.dom,org.w3c.dom.bootstrap,org.w3c.dom.css,org.w3c.dom.events,org.w3c.dom.html,org.w3c.dom.ls,org.w3c.dom.ranges,org.w3c.dom.stylesheets,org.w3c.dom.traversal,org.w3c.dom.views,org.xml.sax,org.xml.sax.ext,org.xml.sax.helpers"), - + CoreOptions.systemProperty("derby.stream.error.file").value("target/derby.log"), mvnBundle("org.ow2.asm", "asm-all"), mvnBundle("org.apache.felix", "org.apache.felix.configadmin"), mvnBundle("org.apache.felix", "org.apache.felix.coordinator"),
Modified: aries/branches/java6support/jpa/itests/jpa-container-testbundle-eclipselink/pom.xml URL: http://svn.apache.org/viewvc/aries/branches/java6support/jpa/itests/jpa-container-testbundle-eclipselink/pom.xml?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/jpa/itests/jpa-container-testbundle-eclipselink/pom.xml (original) +++ aries/branches/java6support/jpa/itests/jpa-container-testbundle-eclipselink/pom.xml Wed Apr 13 18:41:23 2016 @@ -24,7 +24,7 @@ <parent> <groupId>org.apache.aries.jpa.itest</groupId> <artifactId>org.apache.aries.jpa.itest.parent</artifactId> - <version>2.3.0-SNAPSHOT</version> + <version>2.4.0-SNAPSHOT</version> <relativePath>..</relativePath> </parent> Modified: aries/branches/java6support/jpa/itests/jpa-container-testbundle/pom.xml URL: http://svn.apache.org/viewvc/aries/branches/java6support/jpa/itests/jpa-container-testbundle/pom.xml?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/jpa/itests/jpa-container-testbundle/pom.xml (original) +++ aries/branches/java6support/jpa/itests/jpa-container-testbundle/pom.xml Wed Apr 13 18:41:23 2016 @@ -24,7 +24,7 @@ <parent> <groupId>org.apache.aries.jpa.itest</groupId> <artifactId>org.apache.aries.jpa.itest.parent</artifactId> - <version>2.3.0-SNAPSHOT</version> + <version>2.4.0-SNAPSHOT</version> <relativePath>..</relativePath> </parent> Modified: aries/branches/java6support/jpa/itests/pom.xml URL: http://svn.apache.org/viewvc/aries/branches/java6support/jpa/itests/pom.xml?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/jpa/itests/pom.xml (original) +++ aries/branches/java6support/jpa/itests/pom.xml Wed Apr 13 18:41:23 2016 @@ -29,7 +29,7 @@ <parent> <groupId>org.apache.aries.jpa</groupId> <artifactId>org.apache.aries.jpa.parent</artifactId> - <version>2.3.0-SNAPSHOT</version> + <version>2.4.0-SNAPSHOT</version> <relativePath>../jpa-parent</relativePath> </parent> Modified: aries/branches/java6support/jpa/jpa-api/pom.xml URL: http://svn.apache.org/viewvc/aries/branches/java6support/jpa/jpa-api/pom.xml?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/jpa/jpa-api/pom.xml (original) +++ aries/branches/java6support/jpa/jpa-api/pom.xml Wed Apr 13 18:41:23 2016 @@ -24,7 +24,7 @@ <parent> <groupId>org.apache.aries.jpa</groupId> <artifactId>org.apache.aries.jpa.parent</artifactId> - <version>2.3.0-SNAPSHOT</version> + <version>2.4.0-SNAPSHOT</version> <relativePath>../jpa-parent</relativePath> </parent> Modified: aries/branches/java6support/jpa/jpa-blueprint/pom.xml URL: http://svn.apache.org/viewvc/aries/branches/java6support/jpa/jpa-blueprint/pom.xml?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/jpa/jpa-blueprint/pom.xml (original) +++ aries/branches/java6support/jpa/jpa-blueprint/pom.xml Wed Apr 13 18:41:23 2016 @@ -22,7 +22,7 @@ <parent> <groupId>org.apache.aries.jpa</groupId> <artifactId>org.apache.aries.jpa.parent</artifactId> - <version>2.3.0-SNAPSHOT</version> + <version>2.4.0-SNAPSHOT</version> <relativePath>../jpa-parent</relativePath> </parent> <artifactId>org.apache.aries.jpa.blueprint</artifactId> @@ -48,6 +48,7 @@ <dependency> <groupId>org.osgi</groupId> <artifactId>org.osgi.compendium</artifactId> + <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.aries.blueprint</groupId> Modified: aries/branches/java6support/jpa/jpa-blueprint/src/main/java/org/apache/aries/jpa/blueprint/impl/JpaComponentProcessor.java URL: http://svn.apache.org/viewvc/aries/branches/java6support/jpa/jpa-blueprint/src/main/java/org/apache/aries/jpa/blueprint/impl/JpaComponentProcessor.java?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/jpa/jpa-blueprint/src/main/java/org/apache/aries/jpa/blueprint/impl/JpaComponentProcessor.java (original) +++ aries/branches/java6support/jpa/jpa-blueprint/src/main/java/org/apache/aries/jpa/blueprint/impl/JpaComponentProcessor.java Wed Apr 13 18:41:23 2016 @@ -38,10 +38,12 @@ import org.apache.aries.blueprint.PassTh import org.apache.aries.blueprint.mutable.MutableBeanMetadata; import org.apache.aries.blueprint.mutable.MutableRefMetadata; import org.apache.aries.blueprint.mutable.MutableReferenceMetadata; +import org.apache.aries.blueprint.mutable.MutableServiceMetadata; import org.osgi.framework.Bundle; import org.osgi.service.blueprint.container.BlueprintContainer; import org.osgi.service.blueprint.reflect.ComponentMetadata; import org.osgi.service.blueprint.reflect.ReferenceMetadata; +import org.osgi.service.blueprint.reflect.Target; import org.osgi.service.coordinator.Coordinator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -69,8 +71,17 @@ public class JpaComponentProcessor imple Set<String> components = new HashSet<String>(cdr.getComponentDefinitionNames()); for (String component : components) { ComponentMetadata compDef = cdr.getComponentDefinition(component); + if (compDef instanceof MutableBeanMetadata && !((MutableBeanMetadata)compDef).isProcessor()) { + // Normal bean def handleComponent((MutableBeanMetadata)compDef, bundle, cdr, container); + } else if(compDef instanceof MutableServiceMetadata) { + // Bean inlined into service def + MutableServiceMetadata sMeta = (MutableServiceMetadata)compDef; + Target target = sMeta.getServiceComponent(); + if (target instanceof MutableBeanMetadata) { + handleComponent((MutableBeanMetadata)target, bundle, cdr, container); + } } } } Modified: aries/branches/java6support/jpa/jpa-container-eclipselink-adapter/pom.xml URL: http://svn.apache.org/viewvc/aries/branches/java6support/jpa/jpa-container-eclipselink-adapter/pom.xml?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/jpa/jpa-container-eclipselink-adapter/pom.xml (original) +++ aries/branches/java6support/jpa/jpa-container-eclipselink-adapter/pom.xml Wed Apr 13 18:41:23 2016 @@ -24,7 +24,7 @@ <parent> <groupId>org.apache.aries.jpa</groupId> <artifactId>org.apache.aries.jpa.parent</artifactId> - <version>2.3.0-SNAPSHOT</version> + <version>2.4.0-SNAPSHOT</version> <relativePath>../jpa-parent</relativePath> </parent> Modified: aries/branches/java6support/jpa/jpa-container/osgi.bnd URL: http://svn.apache.org/viewvc/aries/branches/java6support/jpa/jpa-container/osgi.bnd?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/jpa/jpa-container/osgi.bnd (original) +++ aries/branches/java6support/jpa/jpa-container/osgi.bnd Wed Apr 13 18:41:23 2016 @@ -3,4 +3,5 @@ Import-Package: \ javax.persistence.spi;version="[1.1,3)", \ * Bundle-Activator: org.apache.aries.jpa.container.impl.Activator - +Export-Service: \ + javax.persistence.EntityManagerFactory Modified: aries/branches/java6support/jpa/jpa-container/pom.xml URL: http://svn.apache.org/viewvc/aries/branches/java6support/jpa/jpa-container/pom.xml?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/jpa/jpa-container/pom.xml (original) +++ aries/branches/java6support/jpa/jpa-container/pom.xml Wed Apr 13 18:41:23 2016 @@ -22,7 +22,7 @@ <parent> <groupId>org.apache.aries.jpa</groupId> <artifactId>org.apache.aries.jpa.parent</artifactId> - <version>2.3.0-SNAPSHOT</version> + <version>2.4.0-SNAPSHOT</version> <relativePath>../jpa-parent</relativePath> </parent> <artifactId>org.apache.aries.jpa.container</artifactId> Modified: aries/branches/java6support/jpa/jpa-container/src/main/java/org/apache/aries/jpa/container/impl/PersistenceProviderTracker.java URL: http://svn.apache.org/viewvc/aries/branches/java6support/jpa/jpa-container/src/main/java/org/apache/aries/jpa/container/impl/PersistenceProviderTracker.java?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/jpa/jpa-container/src/main/java/org/apache/aries/jpa/container/impl/PersistenceProviderTracker.java (original) +++ aries/branches/java6support/jpa/jpa-container/src/main/java/org/apache/aries/jpa/container/impl/PersistenceProviderTracker.java Wed Apr 13 18:41:23 2016 @@ -105,7 +105,7 @@ public class PersistenceProviderTracker EntityManagerFactory emf = provider.createContainerEntityManagerFactory(punit, null); emf.close(); } catch (Exception e) { - LOGGER.warn(e.getMessage(), e); + LOGGER.debug("Error while creating the Dummy EntityManagerFactory to allow weaving.", e); } punit.setJtaDataSource(null); punit.setNonJtaDataSource(null); Modified: aries/branches/java6support/jpa/jpa-features/pom.xml URL: http://svn.apache.org/viewvc/aries/branches/java6support/jpa/jpa-features/pom.xml?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/jpa/jpa-features/pom.xml (original) +++ aries/branches/java6support/jpa/jpa-features/pom.xml Wed Apr 13 18:41:23 2016 @@ -22,9 +22,12 @@ <parent> <groupId>org.apache.aries.jpa</groupId> <artifactId>org.apache.aries.jpa.parent</artifactId> - <version>2.3.0-SNAPSHOT</version> + <version>2.4.0-SNAPSHOT</version> <relativePath>../jpa-parent</relativePath> </parent> + <properties> + <karaf.version>4.0.3</karaf.version> + </properties> <artifactId>jpa-features</artifactId> <name>Apache Aries JPA features</name> <description>Karaf features for Aries JPA</description> @@ -56,7 +59,7 @@ <groupId>org.apache.karaf.features</groupId> <artifactId>framework</artifactId> <type>kar</type> - <version>4.0.1</version> + <version>${karaf.version}</version> <scope>provided</scope> </dependency> </dependencies> @@ -66,7 +69,7 @@ <plugin> <groupId>org.apache.karaf.tooling</groupId> <artifactId>karaf-maven-plugin</artifactId> - <version>4.0.1</version> + <version>${karaf.version}</version> <configuration> </configuration> <executions> @@ -80,6 +83,7 @@ <addBundlesToPrimaryFeature>false</addBundlesToPrimaryFeature> </configuration> </execution> + <!-- <execution> <id>verify</id> <phase>process-resources</phase> @@ -88,7 +92,7 @@ </goals> <configuration> <descriptors> - <descriptor>mvn:org.apache.karaf.features/framework/4.0.1/xml/features</descriptor> + <descriptor>mvn:org.apache.karaf.features/framework/${karaf.version}/xml/features</descriptor> <descriptor>file:${project.build.directory}/feature/feature.xml</descriptor> </descriptors> <distribution>org.apache.karaf.features:framework</distribution> @@ -99,6 +103,7 @@ <ignoreMissingConditions>true</ignoreMissingConditions> </configuration> </execution> + --> </executions> </plugin> <plugin> Modified: aries/branches/java6support/jpa/jpa-parent/pom.xml URL: http://svn.apache.org/viewvc/aries/branches/java6support/jpa/jpa-parent/pom.xml?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/jpa/jpa-parent/pom.xml (original) +++ aries/branches/java6support/jpa/jpa-parent/pom.xml Wed Apr 13 18:41:23 2016 @@ -28,7 +28,7 @@ <groupId>org.apache.aries.jpa</groupId> <artifactId>org.apache.aries.jpa.parent</artifactId> - <version>2.3.0-SNAPSHOT</version> + <version>2.4.0-SNAPSHOT</version> <name>Apache Aries JPA parent</name> <packaging>pom</packaging> Modified: aries/branches/java6support/jpa/jpa-support/osgi.bnd URL: http://svn.apache.org/viewvc/aries/branches/java6support/jpa/jpa-support/osgi.bnd?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/jpa/jpa-support/osgi.bnd (original) +++ aries/branches/java6support/jpa/jpa-support/osgi.bnd Wed Apr 13 18:41:23 2016 @@ -3,3 +3,8 @@ Import-Package: \ javax.persistence.spi;version="[1.1,3)", \ * Bundle-Activator: org.apache.aries.jpa.support.osgi.impl.Activator +Export-Service: \ + javax.persistence.EntityManager, + org.apache.aries.jpa.template.JpaTemplate +Import-Service:\ + org.osgi.service.coordinator.Coordinator Modified: aries/branches/java6support/jpa/jpa-support/pom.xml URL: http://svn.apache.org/viewvc/aries/branches/java6support/jpa/jpa-support/pom.xml?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/jpa/jpa-support/pom.xml (original) +++ aries/branches/java6support/jpa/jpa-support/pom.xml Wed Apr 13 18:41:23 2016 @@ -22,7 +22,7 @@ <parent> <groupId>org.apache.aries.jpa</groupId> <artifactId>org.apache.aries.jpa.parent</artifactId> - <version>2.3.0-SNAPSHOT</version> + <version>2.4.0-SNAPSHOT</version> <relativePath>../jpa-parent</relativePath> </parent> <artifactId>org.apache.aries.jpa.support</artifactId> @@ -52,10 +52,12 @@ <dependency> <groupId>org.osgi</groupId> <artifactId>org.osgi.core</artifactId> + <scope>provided</scope> </dependency> <dependency> <groupId>org.osgi</groupId> <artifactId>org.osgi.compendium</artifactId> + <scope>provided</scope> </dependency> </dependencies> Modified: aries/branches/java6support/jpa/pom.xml URL: http://svn.apache.org/viewvc/aries/branches/java6support/jpa/pom.xml?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/jpa/pom.xml (original) +++ aries/branches/java6support/jpa/pom.xml Wed Apr 13 18:41:23 2016 @@ -24,7 +24,7 @@ <parent> <groupId>org.apache.aries.jpa</groupId> <artifactId>org.apache.aries.jpa.parent</artifactId> - <version>2.3.0-SNAPSHOT</version> + <version>2.4.0-SNAPSHOT</version> <relativePath>jpa-parent</relativePath> </parent> @@ -49,6 +49,7 @@ <module>jpa-support</module> <module>jpa-blueprint</module> <module>jpa-container-eclipselink-adapter</module> + <module>jpa-repository</module> <module>examples</module> <module>jpa-features</module> <module>itests</module> Modified: aries/branches/java6support/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/gen/ProxySubclassAdapter.java URL: http://svn.apache.org/viewvc/aries/branches/java6support/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/gen/ProxySubclassAdapter.java?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/gen/ProxySubclassAdapter.java (original) +++ aries/branches/java6support/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/gen/ProxySubclassAdapter.java Wed Apr 13 18:41:23 2016 @@ -146,17 +146,7 @@ public class ProxySubclassAdapter extend // So what we do is build up the calling of the superclasses constructor using nulls and default values. This means that the // class bytes can be verified by the JVM, and then in the ProxySubclassGenerator, we load the class without invoking the // constructor. - String constructorString = constructors[0].toGenericString(); - Method constructor = null; - if (constructorString.indexOf(")") != -1) { - //If constructor throws two or more exceptions, getMethod(String) will report a StringIndexOutOfBounds exception, - //so attempt to remove exceptions - constructor = Method.getMethod(constructorString.substring(0, constructorString.indexOf(")") + 1)); - } else { - //As a backup, just pass in the generic string as before - constructor = Method.getMethod(constructorString); - } - + Method constructor = Method.getMethod(constructors[0]); Type[] argTypes = constructor.getArgumentTypes(); if (argTypes.length == 0) { methodAdapter.invokeConstructor(Type.getType(superclassClass), new Method("<init>", Type.VOID_TYPE, NO_ARGS)); Modified: aries/branches/java6support/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/interfaces/InterfaceCombiningClassAdapter.java URL: http://svn.apache.org/viewvc/aries/branches/java6support/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/interfaces/InterfaceCombiningClassAdapter.java?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/interfaces/InterfaceCombiningClassAdapter.java (original) +++ aries/branches/java6support/proxy/proxy-impl/src/main/java/org/apache/aries/proxy/impl/interfaces/InterfaceCombiningClassAdapter.java Wed Apr 13 18:41:23 2016 @@ -84,16 +84,21 @@ final class InterfaceCombiningClassAdapt @Override public final MethodVisitor visitMethod(int access, String name, String desc, - String sig, String[] arg4) { - //If we already implement this method (from another interface) then we don't - //want a duplicate. We also don't want to copy any static init blocks (these - //initialize static fields on the interface that we don't copy - if(adapter.getKnownMethods().contains(new Method(name, desc)) || - "<clinit>".equals(name)) - return null; - else {//We're going to implement this method, so make it non abstract! - return adapter.visitMethod(access, name, desc, null, arg4); - } + String sig, String[] arg4) { + //If we already implement this method (from another interface) then we don't + //want a duplicate. We also don't want to copy any static init blocks (these + //initialize static fields on the interface that we don't copy + if(adapter.getKnownMethods().contains(new Method(name, desc)) || + "<clinit>".equals(name)) { + return null; + } + else if(((access & (ACC_PRIVATE|ACC_SYNTHETIC)) == (ACC_PRIVATE|ACC_SYNTHETIC))) { + // private, synthetic methods on interfaces don't need to be proxied. + return null; + } + else {//We're going to implement this method, so make it non abstract! + return adapter.visitMethod(access, name, desc, null, arg4); + } } /** Modified: aries/branches/java6support/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/ProxySubclassGeneratorTest.java URL: http://svn.apache.org/viewvc/aries/branches/java6support/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/ProxySubclassGeneratorTest.java?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/ProxySubclassGeneratorTest.java (original) +++ aries/branches/java6support/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/ProxySubclassGeneratorTest.java Wed Apr 13 18:41:23 2016 @@ -142,7 +142,7 @@ public class ProxySubclassGeneratorTest assertEquals("Sets were not the same", expectedMethods, generatedMethods); } - + /** * Test a method marked final */ @@ -180,7 +180,18 @@ public class ProxySubclassGeneratorTest assertNotNull("The new instance was null", o); } - + + /** + * Test a generating proxy class of class with package access constructor. + */ + @SuppressWarnings("unchecked") + @Test + public void testPackageAccessCtor() throws Exception { + Class<ProxyTestClassPackageAccessCtor> proxyClass = + (Class<ProxyTestClassPackageAccessCtor>) ProxySubclassGenerator.getProxySubclass(ProxyTestClassPackageAccessCtor.class); + ProxyTestClassPackageAccessCtor proxy = (ProxyTestClassPackageAccessCtor) getProxyInstance(proxyClass); + assertNotNull("The new instance was null", proxy); + } // /** // * Test object equality between real and proxy using a Collaborator // */ Modified: aries/branches/java6support/proxy/proxy-itests/src/test/java/org/apache/aries/proxy/itests/AbstractBasicProxyTest.java URL: http://svn.apache.org/viewvc/aries/branches/java6support/proxy/proxy-itests/src/test/java/org/apache/aries/proxy/itests/AbstractBasicProxyTest.java?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/proxy/proxy-itests/src/test/java/org/apache/aries/proxy/itests/AbstractBasicProxyTest.java (original) +++ aries/branches/java6support/proxy/proxy-itests/src/test/java/org/apache/aries/proxy/itests/AbstractBasicProxyTest.java Wed Apr 13 18:41:23 2016 @@ -54,6 +54,26 @@ public abstract class AbstractBasicProxy } /** + * This method checks that we correctly proxy an interface with default methods on java 8 + */ + @Test + public void checkProxydefaultMethodInterface() throws UnableToProxyException + { + Bundle b = bundleContext.getBundle(); + Callable<Object> c = new TestCallable(); + Collection<Class<?>> classes = new ArrayList<Class<?>>(); + // proxy an interface with a default methods (on Java 8). + classes.add(java.lang.CharSequence.class); + try { + mgr.createDelegatingProxy(b, classes, c, null); + } catch (FinalModifierException e) { + String msg = e.getMessage(); + assertEquals("The message didn't look right", "The class " + TestCallable.class.getName() + " is final.", msg); + assertTrue("The message didn't appear in the toString", e.toString().endsWith(msg)); + } + } + + /** * This method checks that we correctly fail to proxy a class with final methods. * It also does a quick validation on the exception message. */ Modified: aries/branches/java6support/spi-fly/pom.xml URL: http://svn.apache.org/viewvc/aries/branches/java6support/spi-fly/pom.xml?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/spi-fly/pom.xml (original) +++ aries/branches/java6support/spi-fly/pom.xml Wed Apr 13 18:41:23 2016 @@ -31,7 +31,7 @@ <groupId>org.apache.aries.spifly</groupId> <artifactId>spifly</artifactId> <name>Apache Aries SPI Fly</name> - <version>1.0.7-SNAPSHOT</version> + <version>1.0.9-SNAPSHOT</version> <packaging>pom</packaging> <description> SPI support for OSGi @@ -49,7 +49,9 @@ <module>spi-fly-dynamic-bundle</module> <module>spi-fly-static-tool</module> <module>spi-fly-static-bundle</module> + <!-- <module>spi-fly-examples</module> + --> </modules> </project> Modified: aries/branches/java6support/spi-fly/spi-fly-core/pom.xml URL: http://svn.apache.org/viewvc/aries/branches/java6support/spi-fly/spi-fly-core/pom.xml?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/spi-fly/spi-fly-core/pom.xml (original) +++ aries/branches/java6support/spi-fly/spi-fly-core/pom.xml Wed Apr 13 18:41:23 2016 @@ -30,7 +30,7 @@ <groupId>org.apache.aries.spifly</groupId> <artifactId>org.apache.aries.spifly.core-internal</artifactId> - <version>1.0.7-SNAPSHOT</version> + <version>1.0.9-SNAPSHOT</version> <packaging>jar</packaging> <name>Apache Aries SPI Fly Core (internal module)</name> <description> Modified: aries/branches/java6support/spi-fly/spi-fly-dynamic-bundle/pom.xml URL: http://svn.apache.org/viewvc/aries/branches/java6support/spi-fly/spi-fly-dynamic-bundle/pom.xml?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/spi-fly/spi-fly-dynamic-bundle/pom.xml (original) +++ aries/branches/java6support/spi-fly/spi-fly-dynamic-bundle/pom.xml Wed Apr 13 18:41:23 2016 @@ -30,7 +30,7 @@ <groupId>org.apache.aries.spifly</groupId> <artifactId>org.apache.aries.spifly.dynamic.bundle</artifactId> - <version>1.0.7-SNAPSHOT</version> + <version>1.0.9-SNAPSHOT</version> <packaging>bundle</packaging> <name>Apache Aries SPI Fly Dynamic Weaving Bundle</name> <description> @@ -58,7 +58,7 @@ <dependency> <groupId>org.apache.aries.spifly</groupId> <artifactId>org.apache.aries.spifly.core-internal</artifactId> - <version>1.0.7-SNAPSHOT</version> + <version>1.0.9-SNAPSHOT</version> <exclusions> <exclusion> <groupId>org.osgi</groupId> @@ -75,7 +75,7 @@ <dependency> <groupId>org.apache.aries.spifly</groupId> <artifactId>org.apache.aries.spifly.weaver-internal</artifactId> - <version>1.0.7-SNAPSHOT</version> + <version>1.0.9-SNAPSHOT</version> </dependency> <dependency> Modified: aries/branches/java6support/spi-fly/spi-fly-static-bundle/pom.xml URL: http://svn.apache.org/viewvc/aries/branches/java6support/spi-fly/spi-fly-static-bundle/pom.xml?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/spi-fly/spi-fly-static-bundle/pom.xml (original) +++ aries/branches/java6support/spi-fly/spi-fly-static-bundle/pom.xml Wed Apr 13 18:41:23 2016 @@ -30,7 +30,7 @@ <groupId>org.apache.aries.spifly</groupId> <artifactId>org.apache.aries.spifly.static.bundle</artifactId> - <version>1.0.7-SNAPSHOT</version> + <version>1.0.9-SNAPSHOT</version> <packaging>bundle</packaging> <name>Apache Aries SPI Fly Static Weaving Bundle</name> <description> @@ -52,7 +52,7 @@ <dependency> <groupId>org.apache.aries.spifly</groupId> <artifactId>org.apache.aries.spifly.core-internal</artifactId> - <version>1.0.7-SNAPSHOT</version> + <version>1.0.9-SNAPSHOT</version> </dependency> <dependency> Modified: aries/branches/java6support/spi-fly/spi-fly-static-tool/pom.xml URL: http://svn.apache.org/viewvc/aries/branches/java6support/spi-fly/spi-fly-static-tool/pom.xml?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/spi-fly/spi-fly-static-tool/pom.xml (original) +++ aries/branches/java6support/spi-fly/spi-fly-static-tool/pom.xml Wed Apr 13 18:41:23 2016 @@ -30,7 +30,7 @@ <groupId>org.apache.aries.spifly</groupId> <artifactId>org.apache.aries.spifly.static.tool</artifactId> - <version>1.0.7-SNAPSHOT</version> + <version>1.0.9-SNAPSHOT</version> <packaging>jar</packaging> <name>Apache Aries SPI Fly Static Weaving Tool</name> <description> @@ -53,13 +53,13 @@ <dependency> <groupId>org.apache.aries.spifly</groupId> <artifactId>org.apache.aries.spifly.core-internal</artifactId> - <version>1.0.7-SNAPSHOT</version> + <version>1.0.9-SNAPSHOT</version> </dependency> <dependency> <groupId>org.apache.aries.spifly</groupId> <artifactId>org.apache.aries.spifly.weaver-internal</artifactId> - <version>1.0.7-SNAPSHOT</version> + <version>1.0.9-SNAPSHOT</version> </dependency> <dependency> Modified: aries/branches/java6support/spi-fly/spi-fly-weaver/pom.xml URL: http://svn.apache.org/viewvc/aries/branches/java6support/spi-fly/spi-fly-weaver/pom.xml?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/spi-fly/spi-fly-weaver/pom.xml (original) +++ aries/branches/java6support/spi-fly/spi-fly-weaver/pom.xml Wed Apr 13 18:41:23 2016 @@ -30,7 +30,7 @@ <groupId>org.apache.aries.spifly</groupId> <artifactId>org.apache.aries.spifly.weaver-internal</artifactId> - <version>1.0.7-SNAPSHOT</version> + <version>1.0.9-SNAPSHOT</version> <packaging>jar</packaging> <name>Apache Aries SPI Fly Weaver (internal module)</name> @@ -51,7 +51,7 @@ <dependency> <groupId>org.apache.aries.spifly</groupId> <artifactId>org.apache.aries.spifly.core-internal</artifactId> - <version>1.0.7-SNAPSHOT</version> + <version>1.0.9-SNAPSHOT</version> </dependency> <dependency> Modified: aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/BasicSubsystem.java URL: http://svn.apache.org/viewvc/aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/BasicSubsystem.java?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/BasicSubsystem.java (original) +++ aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/BasicSubsystem.java Wed Apr 13 18:41:23 2016 @@ -32,6 +32,7 @@ import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import java.util.concurrent.locks.ReentrantLock; import org.apache.aries.subsystem.AriesSubsystem; import org.apache.aries.subsystem.core.archive.AriesProvisionDependenciesDirective; @@ -295,8 +296,8 @@ public class BasicSubsystem implements R public void start() { SecurityManager.checkExecutePermission(this); // Changing the autostart setting must be privileged because of file IO. - // It cannot be done within SartAction because we only want to change it - // on an explicit start operation but StartAction is also used for + // It cannot be done within StartAction because we only want to change + // it on an explicit start operation but StartAction is also used for // implicit operations. AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override @@ -621,6 +622,11 @@ public class BasicSubsystem implements R } } + private final ReentrantLock stateChangeLock = new ReentrantLock(); + ReentrantLock stateChangeLock() { + return stateChangeLock; + } + private String getDeploymentManifestHeaderValue(String name) { DeploymentManifest manifest = getDeploymentManifest(); if (manifest == null) @@ -754,8 +760,8 @@ public class BasicSubsystem implements R } } - void computeDependenciesPostInstallation() throws IOException { - resource.computeDependencies(null); + void computeDependenciesPostInstallation(Coordination coordination) throws IOException { + resource.computeDependencies(null, coordination); ProvisionResourceHeader header = resource.computeProvisionResourceHeader(); setDeploymentManifest( new DeploymentManifest.Builder() Modified: aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/DependencyCalculator.java URL: http://svn.apache.org/viewvc/aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/DependencyCalculator.java?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/DependencyCalculator.java (original) +++ aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/DependencyCalculator.java Wed Apr 13 18:41:23 2016 @@ -83,8 +83,9 @@ public class DependencyCalculator { @Override public int insertHostedCapability(List<Capability> capabilities, HostedCapability hostedCapability) { - capabilities.add(hostedCapability); - return capabilities.size() - 1; + int sz = capabilities.size(); + capabilities.add(sz, hostedCapability); + return sz; } } Modified: aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/InstallAction.java URL: http://svn.apache.org/viewvc/aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/InstallAction.java?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/InstallAction.java (original) +++ aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/InstallAction.java Wed Apr 13 18:41:23 2016 @@ -41,57 +41,68 @@ public class InstallAction implements Pr @Override public BasicSubsystem run() { - State state = parent.getState(); - if (State.INSTALLING.equals(state)) { - throw new SubsystemException("A child subsystem may not be installed while the parent is in the INSTALLING state"); - } - // Initialization of a null coordination must be privileged and, - // therefore, occur in the run() method rather than in the constructor. - Coordination coordination = Utils.createCoordination(parent); + // Doesn't appear to be any need of protecting against re-entry in the + // case of installation. BasicSubsystem result = null; + // 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 { - TargetRegion region = new TargetRegion(parent); - SubsystemResource ssr = new SubsystemResource(location, content, parent); - result = Activator.getInstance().getSubsystems().getSubsystemByLocation(location); - if (result != null) { - checkLifecyclePermission(result); - if (!region.contains(result)) - throw new SubsystemException("Location already exists but existing subsystem is not part of target region: " + location); - if (!(result.getSymbolicName().equals(ssr.getSubsystemManifest().getSubsystemSymbolicNameHeader().getSymbolicName()) - && result.getVersion().equals(ssr.getSubsystemManifest().getSubsystemVersionHeader().getVersion()) - && result.getType().equals(ssr.getSubsystemManifest().getSubsystemTypeHeader().getType()))) - throw new SubsystemException("Location already exists but symbolic name, version, and type are not the same: " + location); - return (BasicSubsystem)ResourceInstaller.newInstance(coordination, result, parent).install(); + State state = parent.getState(); + if (State.INSTALLING.equals(state)) { + throw new SubsystemException("A child subsystem may not be installed while the parent is in the INSTALLING state"); } - result = (BasicSubsystem)region.find( - ssr.getSubsystemManifest().getSubsystemSymbolicNameHeader().getSymbolicName(), - ssr.getSubsystemManifest().getSubsystemVersionHeader().getVersion()); - if (result != null) { + // Initialization of a null coordination must be privileged and, + // therefore, occur in the run() method rather than in the constructor. + Coordination coordination = Utils.createCoordination(parent); + try { + TargetRegion region = new TargetRegion(parent); + SubsystemResource ssr = new SubsystemResource(location, content, parent, coordination); + result = Activator.getInstance().getSubsystems().getSubsystemByLocation(location); + if (result != null) { + if (!region.contains(result)) + throw new SubsystemException("Location already exists but existing subsystem is not part of target region: " + location); + if (!(result.getSymbolicName().equals(ssr.getSubsystemManifest().getSubsystemSymbolicNameHeader().getSymbolicName()) + && result.getVersion().equals(ssr.getSubsystemManifest().getSubsystemVersionHeader().getVersion()) + && result.getType().equals(ssr.getSubsystemManifest().getSubsystemTypeHeader().getType()))) + throw new SubsystemException("Location already exists but symbolic name, version, and type are not the same: " + location); + } + else { + result = (BasicSubsystem)region.find( + ssr.getSubsystemManifest().getSubsystemSymbolicNameHeader().getSymbolicName(), + ssr.getSubsystemManifest().getSubsystemVersionHeader().getVersion()); + if (result != null) { + if (!result.getType().equals(ssr.getSubsystemManifest().getSubsystemTypeHeader().getType())) + throw new SubsystemException("Subsystem already exists in target region but has a different type: " + location); + } + else { + result = new BasicSubsystem(ssr, deploymentManifest); + } + } checkLifecyclePermission(result); - if (!result.getType().equals(ssr.getSubsystemManifest().getSubsystemTypeHeader().getType())) - throw new SubsystemException("Subsystem already exists in target region but has a different type: " + location); return (BasicSubsystem)ResourceInstaller.newInstance(coordination, result, parent).install(); } - result = new BasicSubsystem(ssr, deploymentManifest); - checkLifecyclePermission(result); - return (BasicSubsystem)ResourceInstaller.newInstance(coordination, result, parent).install(); - } - catch (Throwable t) { - coordination.fail(t); - } - finally { - try { - coordination.end(); + catch (Throwable t) { + coordination.fail(t); } - catch (CoordinationException e) { - Throwable t = e.getCause(); - if (t instanceof SubsystemException) - throw (SubsystemException)t; - if (t instanceof SecurityException) - throw (SecurityException)t; - throw new SubsystemException(t); + finally { + try { + coordination.end(); + } + catch (CoordinationException e) { + Throwable t = e.getCause(); + if (t instanceof SubsystemException) + throw (SubsystemException)t; + if (t instanceof SecurityException) + throw (SecurityException)t; + throw new SubsystemException(t); + } } } + finally { + // Release the global write lock. + LockingStrategy.writeUnlock(); + } return result; } Modified: aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ResolveContext.java URL: http://svn.apache.org/viewvc/aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ResolveContext.java?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ResolveContext.java (original) +++ aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ResolveContext.java Wed Apr 13 18:41:23 2016 @@ -15,6 +15,7 @@ package org.apache.aries.subsystem.core. import java.io.IOException; import java.net.URISyntaxException; +import java.security.AccessController; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -27,6 +28,7 @@ import org.apache.aries.subsystem.core.a import org.apache.aries.subsystem.core.archive.SubsystemTypeHeader; import org.apache.aries.subsystem.core.internal.BundleResourceInstaller.BundleConstituent; import org.apache.aries.subsystem.core.internal.DependencyCalculator.MissingCapability; +import org.apache.aries.subsystem.core.internal.StartAction.Restriction; import org.apache.aries.subsystem.core.repository.Repository; import org.eclipse.equinox.region.Region; import org.osgi.framework.BundleException; @@ -42,6 +44,7 @@ import org.osgi.resource.Requirement; import org.osgi.resource.Resource; import org.osgi.resource.Wiring; import org.osgi.service.resolver.HostedCapability; +import org.osgi.service.subsystem.Subsystem.State; import org.osgi.service.subsystem.SubsystemException; public class ResolveContext extends org.osgi.service.resolver.ResolveContext { @@ -61,9 +64,40 @@ public class ResolveContext extends org. repositoryServiceRepository = new RepositoryServiceRepository(); systemRepository = Activator.getInstance().getSystemRepository(); } + + private void installDependenciesOfRequirerIfNecessary(Requirement requirement) { + if (requirement == null) { + return; + } + Resource requirer = requirement.getResource(); + if (resource.equals(requirer)) { + return; + } + Collection<BasicSubsystem> subsystems; + if (requirer instanceof BasicSubsystem) { + BasicSubsystem subsystem = (BasicSubsystem)requirer; + subsystems = Collections.singletonList(subsystem); + } + else if (requirer instanceof BundleRevision) { + BundleRevision revision = (BundleRevision)requirer; + BundleConstituent constituent = new BundleConstituent(null, revision); + subsystems = Activator.getInstance().getSubsystems().getSubsystemsByConstituent(constituent); + } + else { + return; + } + for (BasicSubsystem subsystem : subsystems) { + if (Utils.isProvisionDependenciesInstall(subsystem) + || !State.INSTALLING.equals(subsystem.getState())) { + continue; + } + AccessController.doPrivileged(new StartAction(subsystem, subsystem, subsystem, Restriction.INSTALL_ONLY)); + } + } @Override public List<Capability> findProviders(Requirement requirement) { + installDependenciesOfRequirerIfNecessary(requirement); ArrayList<Capability> result = new ArrayList<Capability>(); try { // Only check the system repository for osgi.ee and osgi.native @@ -160,7 +194,8 @@ public class ResolveContext extends org. } private boolean addDependenciesFromSystemRepository(Requirement requirement, List<Capability> capabilities) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException { - return addDependencies(systemRepository, requirement, capabilities, true); + boolean result = addDependencies(systemRepository, requirement, capabilities, true); + return result; } private void addValidCapabilities(Collection<Capability> from, Collection<Capability> to, Requirement requirement, boolean validate) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException { @@ -263,11 +298,12 @@ public class ResolveContext extends org. else { // This is an already installed resource from the system repository. if (Utils.isBundle(resource)) { - if (this.resource.getSubsystemManifest().getSubsystemTypeHeader().getAriesProvisionDependenciesDirective().isResolve()) { + if (isContent(resource) + && this.resource.getSubsystemManifest().getSubsystemTypeHeader().getAriesProvisionDependenciesDirective().isResolve()) { // If we get here with a subsystem that is // apache-aries-provision-dependencies:=resolve, it means // that a restart has occurred with the subsystem in the - // INSTALLING state. It's content has already been installed. + // INSTALLING state. Its content has already been installed. // However, because the sharing policy has not yet been set, // we must treat it similarly to the installable content case // above. Modified: aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StartAction.java URL: http://svn.apache.org/viewvc/aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StartAction.java?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StartAction.java (original) +++ aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StartAction.java Wed Apr 13 18:41:23 2016 @@ -14,13 +14,12 @@ package org.apache.aries.subsystem.core.internal; import java.io.IOException; -import java.net.URISyntaxException; import java.security.AccessController; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.EnumSet; -import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map.Entry; import java.util.Set; @@ -50,7 +49,6 @@ import org.osgi.resource.Resource; import org.osgi.service.coordinator.Coordination; import org.osgi.service.coordinator.CoordinationException; import org.osgi.service.coordinator.Participant; -import org.osgi.service.resolver.ResolutionException; import org.osgi.service.subsystem.Subsystem; import org.osgi.service.subsystem.Subsystem.State; import org.osgi.service.subsystem.SubsystemConstants; @@ -59,151 +57,299 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class StartAction extends AbstractAction { - private static final Logger logger = LoggerFactory.getLogger(StartAction.class); + public static enum Restriction { + NONE, + INSTALL_ONLY, + RESOLVE_ONLY + } - private static final ThreadLocal<Set<Subsystem>> subsystemsStartingOnCurrentThread = new ThreadLocal<Set<Subsystem>>() { - @Override - protected Set<Subsystem> initialValue() { - return new HashSet<Subsystem>(); - } - }; + private static final Logger logger = LoggerFactory.getLogger(StartAction.class); private final Coordination coordination; private final BasicSubsystem instigator; - private final boolean resolveOnly; + private final Restriction restriction; public StartAction(BasicSubsystem instigator, BasicSubsystem requestor, BasicSubsystem target) { - this(instigator, requestor, target, false); + this(instigator, requestor, target, Restriction.NONE); } - public StartAction(BasicSubsystem instigator, BasicSubsystem requestor, BasicSubsystem target, boolean resolveOnly) { - this(instigator, requestor, target, null, resolveOnly); + public StartAction(BasicSubsystem instigator, BasicSubsystem requestor, BasicSubsystem target, Restriction restriction) { + this(instigator, requestor, target, null, restriction); } public StartAction(BasicSubsystem instigator, BasicSubsystem requestor, BasicSubsystem target, Coordination coordination) { - this(instigator, requestor, target, coordination, false); + this(instigator, requestor, target, coordination, Restriction.NONE); } - public StartAction(BasicSubsystem instigator, BasicSubsystem requestor, BasicSubsystem target, Coordination coordination, boolean resolveOnly) { + public StartAction(BasicSubsystem instigator, BasicSubsystem requestor, BasicSubsystem target, Coordination coordination, Restriction restriction) { super(requestor, target, false); this.instigator = instigator; this.coordination = coordination; - this.resolveOnly = resolveOnly; + this.restriction = restriction; } - private Object doRun() { - // TODO We now support circular dependencies so a sane locking strategy - // is required now more than ever before. Needs to be much more granular - // (and complex) than this. Perhaps something along the lines of a state - // change lock per subsystem then use a global lock only while acquiring - // the necessary state change locks. - synchronized (StartAction.class) { - State state = target.getState(); - // The following states are illegal. - if (EnumSet.of(State.INSTALL_FAILED, State.UNINSTALLED, State.UNINSTALLING).contains(state)) - throw new SubsystemException("Cannot start from state " + state); - // The following states must wait with the exception of INSTALLING - // combined with apache-aries-provision-dependencies:=resolve. - if ((State.INSTALLING.equals(state) - && Utils.isProvisionDependenciesInstall(target)) - || EnumSet.of(State.RESOLVING, State.STARTING, State.STOPPING).contains(state)) { - waitForStateChange(state); - return new StartAction(instigator, requestor, target, coordination).run(); - } - // The following states mean the requested state has already been attained. - if (State.ACTIVE.equals(state)) - return null; - // Always start if target is content of requestor. - if (!Utils.isContent(requestor, target)) { - // Always start if target is a dependency of requestor. - if (!Utils.isDependency(requestor, target)) { - // Always start if instigator equals target (explicit start). - if (!instigator.equals(target)) { - // Don't start if instigator is root (restart) and target is not ready. - if (instigator.isRoot() && !target.isReadyToStart()) { - return null; - } - } - } - } - Coordination coordination = this.coordination; - if (coordination == null) { - coordination = Utils.createCoordination(target); - } - try { - // If necessary, install the dependencies. - if (State.INSTALLING.equals(target.getState()) && - !Utils.isProvisionDependenciesInstall(target)) { - Collection<Subsystem> subsystems = new ArrayList<Subsystem>(); - subsystems.addAll(Activator.getInstance().getSubsystems().getChildren(target)); - subsystems.addAll(target.getParents()); - for (Subsystem subsystem : subsystems) { - if (State.INSTALLING.equals(subsystem.getState())) { - BasicSubsystem bs = (BasicSubsystem)subsystem; - bs.computeDependenciesPostInstallation(); - new InstallDependencies().install(bs, null, coordination); - bs.setState(State.INSTALLED); - } - } - target.computeDependenciesPostInstallation(); - new InstallDependencies().install(target, null, coordination); - target.setState(State.INSTALLED); - } - // Resolve if necessary. - if (State.INSTALLED.equals(target.getState())) - resolve(target, coordination); - if (resolveOnly) - return null; - target.setState(State.STARTING); - // TODO Need to hold a lock here to guarantee that another start - // operation can't occur when the state goes to RESOLVED. - // Start the subsystem. - List<Resource> resources = new ArrayList<Resource>(Activator.getInstance().getSubsystems().getResourcesReferencedBy(target)); - SubsystemContentHeader header = target.getSubsystemManifest().getSubsystemContentHeader(); - if (header != null) - Collections.sort(resources, new StartResourceComparator(header)); - for (Resource resource : resources) - startResource(resource, coordination); - target.setState(State.ACTIVE); - } catch (Throwable t) { - coordination.fail(t); - // TODO Need to reinstate complete isolation by disconnecting the - // region and transition to INSTALLED. - } finally { - try { - // Don't end the coordination if the subsystem being started - // (i.e. the target) did not begin it. - if (coordination.getName().equals(Utils.computeCoordinationName(target))) - coordination.end(); - } catch (CoordinationException e) { - // If the target's state is INSTALLING then installing the - // dependencies failed, in which case we want to leave it as is. - if (!State.INSTALLING.equals(target.getState())) { - target.setState(State.RESOLVED); - } - Throwable t = e.getCause(); - if (t instanceof SubsystemException) - throw (SubsystemException)t; - throw new SubsystemException(t); - } - } - return null; + private static boolean isTargetStartable(BasicSubsystem instigator, BasicSubsystem requestor, BasicSubsystem target) { + State state = target.getState(); + // The following states are illegal. + if (EnumSet.of(State.INSTALL_FAILED, State.UNINSTALLED).contains(state)) + throw new SubsystemException("Cannot start from state " + state); + // The following states mean the requested state has already been attained. + if (State.ACTIVE.equals(state)) + return false; + // Always start if target is content of requestor. + if (!Utils.isContent(requestor, target)) { + // Always start if target is a dependency of requestor. + if (!Utils.isDependency(requestor, target)) { + // Always start if instigator equals target (explicit start). + if (!instigator.equals(target)) { + // Don't start if instigator is root (restart) and target is not ready. + if (instigator.isRoot() && !target.isReadyToStart()) { + return false; + } + } + } + } + return true; + } + + private void installDependencies(BasicSubsystem target, Coordination coordination) throws Exception { + for (Subsystem parent : target.getParents()) { + AccessController.doPrivileged(new StartAction(instigator, target, (BasicSubsystem)parent, coordination, Restriction.INSTALL_ONLY)); + } + installDependencies(Collections.<Subsystem>singletonList(target), coordination); + for (Subsystem child : Activator.getInstance().getSubsystems().getChildren(target)) { + AccessController.doPrivileged(new StartAction(instigator, target, (BasicSubsystem)child, coordination, Restriction.INSTALL_ONLY)); + } + } + + private static void installDependencies(Collection<Subsystem> subsystems, Coordination coordination) throws Exception { + for (Subsystem subsystem : subsystems) { + if (State.INSTALLING.equals(subsystem.getState())) { + BasicSubsystem bs = (BasicSubsystem)subsystem; + bs.computeDependenciesPostInstallation(coordination); + new InstallDependencies().install(bs, null, coordination); + bs.setState(State.INSTALLED); + } } } + + private Coordination createCoordination() { + Coordination coordination = this.coordination; + if (coordination == null) { + coordination = Utils.createCoordination(target); + } + return coordination; + } + + private static class AffectedResources { + private final List<Resource> resources; + private final Collection<BasicSubsystem> subsystemResources; + + AffectedResources(BasicSubsystem target) { + LinkedHashSet<Resource> resources = new LinkedHashSet<Resource>(); + LinkedHashSet<BasicSubsystem> subsystemResources = new LinkedHashSet<BasicSubsystem>(); + Subsystems subsystems = Activator.getInstance().getSubsystems(); + for (Resource dep : subsystems.getResourcesReferencedBy(target)) { + if (dep instanceof BasicSubsystem + && !subsystems.getChildren(target).contains(dep)) { + subsystemResources.add((BasicSubsystem)dep); + } + else if (dep instanceof BundleRevision) { + BundleConstituent constituent = new BundleConstituent(null, (BundleRevision)dep); + if (!target.getConstituents().contains(constituent)) { + for (BasicSubsystem constituentOf : subsystems.getSubsystemsByConstituent( + new BundleConstituent(null, (BundleRevision)dep))) { + subsystemResources.add(constituentOf); + } + } + } + resources.add(dep); + } + for (Subsystem child : subsystems.getChildren(target)) { + subsystemResources.add((BasicSubsystem)child); + resources.add((BasicSubsystem)child); + } + for (Resource resource : target.getResource().getSharedContent()) { + for (BasicSubsystem constituentOf : subsystems.getSubsystemsByConstituent( + resource instanceof BundleRevision ? new BundleConstituent(null, (BundleRevision)resource) : resource)) { + subsystemResources.add(constituentOf); + } + resources.add(resource); + } + subsystemResources.add(target); + this.resources = new ArrayList<Resource>(resources); + this.subsystemResources = subsystemResources; + } + + List<Resource> resources() { + return resources; + } + + Collection<BasicSubsystem> subsystems() { + return subsystemResources; + } + } + + private static AffectedResources computeAffectedResources(BasicSubsystem target) { + return new AffectedResources(target); + } @Override public Object run() { - Set<Subsystem> subsystems = subsystemsStartingOnCurrentThread.get(); - if (subsystems.contains(target)) { + // Protect against re-entry now that cycles are supported. + if (!LockingStrategy.set(State.STARTING, target)) { return null; } - subsystems.add(target); - try { - return doRun(); - } - finally { - subsystems.remove(target); - } + try { + AffectedResources affectedResources; + // We are now protected against re-entry. + // If necessary, install the dependencies. + if (State.INSTALLING.equals(target.getState()) && !Utils.isProvisionDependenciesInstall(target)) { + // Acquire the global write lock while installing dependencies. + LockingStrategy.writeLock(); + try { + // We are now protected against installs, starts, stops, and uninstalls. + // We need a separate coordination when installing + // dependencies because cleaning up the temporary export + // sharing policies must be done while holding the write lock. + Coordination c = Utils.createCoordination(target); + try { + installDependencies(target, c); + // Associated subsystems must be computed after all dependencies + // are installed because some of the dependencies may be + // subsystems. This is safe to do while only holding the read + // lock since we know that nothing can be added or removed. + affectedResources = computeAffectedResources(target); + for (BasicSubsystem subsystem : affectedResources.subsystems()) { + if (State.INSTALLING.equals(subsystem.getState()) + && !Utils.isProvisionDependenciesInstall(subsystem)) { + installDependencies(subsystem, c); + } + } + // Downgrade to the read lock in order to prevent + // installs and uninstalls but allow starts and stops. + LockingStrategy.readLock(); + } + catch (Throwable t) { + c.fail(t); + } + finally { + // This will clean up the temporary export sharing + // policies. Must be done while holding the write lock. + c.end(); + } + } + finally { + // Release the global write lock as soon as possible. + LockingStrategy.writeUnlock(); + } + } + else { + // Acquire the read lock in order to prevent installs and + // uninstalls but allow starts and stops. + LockingStrategy.readLock(); + } + try { + // We now hold the read lock and are protected against installs + // and uninstalls. + if (Restriction.INSTALL_ONLY.equals(restriction)) { + return null; + } + // Compute associated subsystems here in case (1) they weren't + // computed previously while holding the write lock or (2) they + // were computed previously and more were subsequently added. + // This is safe to do while only holding the read lock since we + // know that nothing can be added or removed. + affectedResources = computeAffectedResources(target); + // Acquire the global mutual exclusion lock while acquiring the + // state change locks of affected subsystems. + LockingStrategy.lock(); + try { + // We are now protected against cycles. + // Acquire the state change locks of affected subsystems. + LockingStrategy.lock(affectedResources.subsystems()); + } + finally { + // Release the global mutual exclusion lock as soon as possible. + LockingStrategy.unlock(); + } + Coordination coordination = this.coordination; + try { + coordination = createCoordination(); + // We are now protected against other starts and stops of the affected subsystems. + if (!isTargetStartable(instigator, requestor, target)) { + return null; + } + + // Resolve if necessary. + if (State.INSTALLED.equals(target.getState())) + resolve(instigator, target, target, coordination, affectedResources.subsystems()); + if (Restriction.RESOLVE_ONLY.equals(restriction)) + return null; + target.setState(State.STARTING); + // Be sure to set the state back to RESOLVED if starting fails. + coordination.addParticipant(new Participant() { + @Override + public void ended(Coordination coordination) throws Exception { + // Nothing. + } + + @Override + public void failed(Coordination coordination) throws Exception { + target.setState(State.RESOLVED); + } + }); + SubsystemContentHeader header = target.getSubsystemManifest().getSubsystemContentHeader(); + if (header != null) + Collections.sort(affectedResources.resources(), new StartResourceComparator(header)); + for (Resource resource : affectedResources.resources()) + startResource(resource, coordination); + target.setState(State.ACTIVE); + + } + catch (Throwable t) { + // We catch exceptions and fail the coordination here to + // ensure we are still holding the state change locks when + // the participant sets the state to RESOLVED. + coordination.fail(t); + } + finally { + try { + // Don't end a coordination that was not begun as part + // of this start action. + if (coordination.getName().equals(Utils.computeCoordinationName(target))) { + coordination.end(); + } + } + finally { + // Release the state change locks of affected subsystems. + LockingStrategy.unlock(affectedResources.subsystems()); + } + } + } + finally { + // Release the read lock. + LockingStrategy.readUnlock(); + } + } + catch (CoordinationException e) { + Throwable t = e.getCause(); + if (t == null) { + throw new SubsystemException(e); + } + if (t instanceof SecurityException) { + throw (SecurityException)t; + } + if (t instanceof SubsystemException) { + throw (SubsystemException)t; + } + throw new SubsystemException(t); + } + finally { + // Protection against re-entry no longer required. + LockingStrategy.unset(State.STARTING, target); + } + return null; } private static Collection<Bundle> getBundles(BasicSubsystem subsystem) { @@ -231,41 +377,21 @@ public class StartAction extends Abstrac subsystem.setState(State.RESOLVED); } - private static void resolveSubsystems(BasicSubsystem subsystem, Coordination coordination) { - //resolve dependencies to ensure framework resolution succeeds - Subsystems subsystems = Activator.getInstance().getSubsystems(); - for (Resource dep : subsystems.getResourcesReferencedBy(subsystem)) { - if (dep instanceof BasicSubsystem - && !subsystems.getChildren(subsystem).contains(dep)) { - resolveSubsystem((BasicSubsystem)dep, coordination); - } - else if (dep instanceof BundleRevision - && !subsystem.getConstituents().contains(dep)) { - for (BasicSubsystem constituentOf : subsystems.getSubsystemsByConstituent( - new BundleConstituent(null, (BundleRevision)dep))) { - resolveSubsystem(constituentOf, coordination); - } - } - } - for (Subsystem child : subsystems.getChildren(subsystem)) { - resolveSubsystem((BasicSubsystem)child, coordination); - } - for (Resource resource : subsystem.getResource().getSharedContent()) { - for (BasicSubsystem constituentOf : subsystems.getSubsystemsByConstituent( - resource instanceof BundleRevision ? new BundleConstituent(null, (BundleRevision)resource) : resource)) { - resolveSubsystem(constituentOf, coordination); - } + private static void resolveSubsystems(BasicSubsystem instigator, BasicSubsystem target, Coordination coordination, Collection<BasicSubsystem> subsystems) throws Exception { + for (BasicSubsystem subsystem : subsystems) { + resolveSubsystem(instigator, target, subsystem, coordination); } } - private static void resolveSubsystem(BasicSubsystem subsystem, Coordination coordination) { + private static void resolveSubsystem(BasicSubsystem instigator, BasicSubsystem target, BasicSubsystem subsystem, Coordination coordination) throws Exception { State state = subsystem.getState(); if (State.INSTALLED.equals(state)) { - AccessController.doPrivileged(new StartAction(subsystem, subsystem, subsystem, coordination, true)); - } - else if (State.INSTALLING.equals(state) - && !Utils.isProvisionDependenciesInstall(subsystem)) { - AccessController.doPrivileged(new StartAction(subsystem, subsystem, subsystem, coordination, true)); + if (target.equals(subsystem)) { + resolve(instigator, target, subsystem, coordination, Collections.<BasicSubsystem>emptyList()); + } + else { + AccessController.doPrivileged(new StartAction(instigator, target, subsystem, coordination, Restriction.RESOLVE_ONLY)); + } } } @@ -280,7 +406,7 @@ public class StartAction extends Abstrac } } - private static void resolve(BasicSubsystem subsystem, Coordination coordination) { + private static void resolve(BasicSubsystem instigator, BasicSubsystem target, BasicSubsystem subsystem, Coordination coordination, Collection<BasicSubsystem> subsystems) { emitResolvingEvent(subsystem); try { // The root subsystem should follow the same event pattern for @@ -289,7 +415,7 @@ public class StartAction extends Abstrac // actually doing the resolution work. if (!subsystem.isRoot()) { setExportIsolationPolicy(subsystem, coordination); - resolveSubsystems(subsystem, coordination); + resolveSubsystems(instigator, target, coordination, subsystems); resolveBundles(subsystem); } emitResolvedEvent(subsystem); @@ -302,7 +428,7 @@ public class StartAction extends Abstrac } } - private static void setExportIsolationPolicy(BasicSubsystem subsystem, Coordination coordination) throws InvalidSyntaxException, IOException, BundleException, URISyntaxException, ResolutionException { + private static void setExportIsolationPolicy(final BasicSubsystem subsystem, Coordination coordination) throws InvalidSyntaxException { if (!subsystem.isComposite()) return; final Region from = ((BasicSubsystem)subsystem.getParents().iterator().next()).getRegion(); @@ -317,15 +443,39 @@ public class StartAction extends Abstrac if (logger.isDebugEnabled()) logger.debug("Establishing region connection: from=" + from + ", to=" + to + ", filter=" + regionFilter); - from.connectRegion(to, regionFilter); + try { + from.connectRegion(to, regionFilter); + } + catch (BundleException e) { + // TODO Assume this means that the export sharing policy has already + // been set. Bad assumption? + return; + } coordination.addParticipant(new Participant() { @Override public void ended(Coordination coordination) throws Exception { - // Nothing. + // It may be necessary to rollback the export sharing policy + // even when the coordination did not fail. For example, this + // might have been a subsystem whose export sharing policy was + // set just in case it offered dependencies for some other + // subsystem. + unsetExportIsolationPolicyIfNecessary(); } @Override public void failed(Coordination coordination) throws Exception { + // Nothing to do because a coordination is always ended. + } + + private void unsetExportIsolationPolicyIfNecessary() throws BundleException, InvalidSyntaxException { + if (!EnumSet.of(State.INSTALLING, State.INSTALLED).contains(subsystem.getState())) { + // The subsystem is either RESOLVED or ACTIVE and therefore + // does not require a rollback. + return; + } + // The subsystem is either INSTALLING or INSTALLED and therefore + // requires a rollback since the export sharing policy must only + // be set upon entering the RESOLVED state. RegionUpdater updater = new RegionUpdater(from, to); updater.addRequirements(null); } @@ -353,13 +503,26 @@ public class StartAction extends Abstrac for (ProvideCapabilityHeader.Clause clause : header.getClauses()) { ProvideCapabilityCapability capability = new ProvideCapabilityCapability(clause, subsystem); String policy = capability.getNamespace(); - StringBuilder filter = new StringBuilder("(&"); - for (Entry<String, Object> attribute : capability.getAttributes().entrySet()) + Set<Entry<String, Object>> entrySet = capability.getAttributes().entrySet(); + StringBuilder filter = new StringBuilder(); + if (entrySet.size() > 1) { + filter.append("(&"); + } + for (Entry<String, Object> attribute : capability.getAttributes().entrySet()) { filter.append('(').append(attribute.getKey()).append('=').append(attribute.getValue()).append(')'); - filter.append(')'); - if (logger.isDebugEnabled()) - logger.debug("Allowing " + policy + " of " + filter); - builder.allow(policy, filter.toString()); + } + if (entrySet.size() > 1) { + filter.append(')'); + } + if (logger.isDebugEnabled()) { + logger.debug("Allowing policy {} with filter {}", policy, filter); + } + if (filter.length() == 0) { + builder.allowAll(policy); + } + else { + builder.allow(policy, filter.toString()); + } } } @@ -452,8 +615,11 @@ public class StartAction extends Abstrac return false; } - private void startSubsystemResource(Resource resource, Coordination coordination) throws IOException { + private void startSubsystemResource(Resource resource, final Coordination coordination) throws IOException { final BasicSubsystem subsystem = (BasicSubsystem)resource; + if (!isTargetStartable(instigator, target, subsystem)) { + return; + } // Subsystems that are content resources of another subsystem must have // their autostart setting set to started. if (Utils.isContent(this.target, subsystem)) @@ -520,4 +686,14 @@ public class StartAction extends Abstrac } logger.error(diagnostics.toString()); } + + static void setExportPolicyOfAllInstallingSubsystemsWithProvisionDependenciesResolve(Coordination coordination) throws InvalidSyntaxException { + for (BasicSubsystem subsystem : Activator.getInstance().getSubsystems().getSubsystems()) { + if (!State.INSTALLING.equals(subsystem.getState()) + || Utils.isProvisionDependenciesInstall(subsystem)) { + continue; + } + setExportIsolationPolicy(subsystem, coordination); + } + } } Modified: aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StartResourceComparator.java URL: http://svn.apache.org/viewvc/aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StartResourceComparator.java?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StartResourceComparator.java (original) +++ aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StartResourceComparator.java Wed Apr 13 18:41:23 2016 @@ -34,7 +34,7 @@ public class StartResourceComparator imp private Integer getStartOrder(Resource r) { SubsystemContentHeader.Clause clause = header.getClause(r); if (clause == null) - return 0; + return -1; return clause.getStartOrder(); } } Modified: aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StopAction.java URL: http://svn.apache.org/viewvc/aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StopAction.java?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StopAction.java (original) +++ aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StopAction.java Wed Apr 13 18:41:23 2016 @@ -17,6 +17,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.EnumSet; +import java.util.LinkedHashSet; import java.util.List; import org.apache.aries.subsystem.ContentHandler; @@ -42,54 +43,102 @@ public class StopAction extends Abstract @Override public Object run() { - checkRoot(); - State state = target.getState(); - if (EnumSet.of(State.INSTALLED, State.RESOLVED).contains(state)) + // Protect against re-entry now that cycles are supported. + if (!LockingStrategy.set(State.STOPPING, target)) { return null; - else if (EnumSet.of(State.INSTALL_FAILED, State.UNINSTALLING, State.UNINSTALLED).contains(state)) - throw new IllegalStateException("Cannot stop from state " + state); - else if (State.INSTALLING.equals(state) && !Utils.isProvisionDependenciesInstall(target)) { - return null; - } - else if (EnumSet.of(State.INSTALLING, State.RESOLVING, State.STARTING, State.STOPPING).contains(state)) { - waitForStateChange(state); - return new StopAction(requestor, target, disableRootCheck).run(); } - target.setState(State.STOPPING); - List<Resource> resources = new ArrayList<Resource>(Activator.getInstance().getSubsystems().getResourcesReferencedBy(target)); - SubsystemContentHeader header = target.getSubsystemManifest().getSubsystemContentHeader(); - if (header != null) { - Collections.sort(resources, new StartResourceComparator(target.getSubsystemManifest().getSubsystemContentHeader())); - Collections.reverse(resources); - } - for (Resource resource : resources) { - // Don't stop the region context bundle. - if (Utils.isRegionContextBundle(resource)) - continue; + try { + // We are now protected against re-entry. + // Acquire the global read lock to prevent installs and uninstalls + // but allow starts and stops. + LockingStrategy.readLock(); try { - stopResource(resource); + // We are now protected against installs and uninstalls. + checkRoot(); + // Compute affected subsystems. This is safe to do while only + // holding the read lock since we know that nothing can be added + // or removed. + LinkedHashSet<BasicSubsystem> subsystems = new LinkedHashSet<BasicSubsystem>(); + subsystems.add(target); + List<Resource> resources = new ArrayList<Resource>(Activator.getInstance().getSubsystems().getResourcesReferencedBy(target)); + for (Resource resource : resources) { + if (resource instanceof BasicSubsystem) { + subsystems.add((BasicSubsystem)resource); + } + } + // Acquire the global mutual exclusion lock while acquiring the + // state change locks of affected subsystems. + LockingStrategy.lock(); + try { + // We are now protected against cycles. + // Acquire the state change locks of affected subsystems. + LockingStrategy.lock(subsystems); + } + finally { + // Release the global mutual exclusion lock as soon as possible. + LockingStrategy.unlock(); + } + try { + // We are now protected against other starts and stops of the affected subsystems. + State state = target.getState(); + if (EnumSet.of(State.INSTALLED, State.INSTALLING, State.RESOLVED).contains(state)) { + // INSTALLING is included because a subsystem may + // persist in this state without being locked when + // apache-aries-provision-dependencies:=resolve. + return null; + } + else if (EnumSet.of(State.INSTALL_FAILED, State.UNINSTALLED).contains(state)) { + throw new IllegalStateException("Cannot stop from state " + state); + } + target.setState(State.STOPPING); + SubsystemContentHeader header = target.getSubsystemManifest().getSubsystemContentHeader(); + if (header != null) { + Collections.sort(resources, new StartResourceComparator(target.getSubsystemManifest().getSubsystemContentHeader())); + Collections.reverse(resources); + } + for (Resource resource : resources) { + // Don't stop the region context bundle. + if (Utils.isRegionContextBundle(resource)) + continue; + try { + stopResource(resource); + } + catch (Exception e) { + logger.error("An error occurred while stopping resource " + resource + " of subsystem " + target, e); + } + } + // TODO Can we automatically assume it actually is resolved? + target.setState(State.RESOLVED); + try { + synchronized (target) { + target.setDeploymentManifest(new DeploymentManifest( + target.getDeploymentManifest(), + null, + target.isAutostart(), + target.getSubsystemId(), + SubsystemIdentifier.getLastId(), + target.getLocation(), + false, + false)); + } + } + catch (Exception e) { + throw new SubsystemException(e); + } + } + finally { + // Release the state change locks of affected subsystems. + LockingStrategy.unlock(subsystems); + } } - catch (Exception e) { - logger.error("An error occurred while stopping resource " + resource + " of subsystem " + target, e); - } - } - // TODO Can we automatically assume it actually is resolved? - target.setState(State.RESOLVED); - try { - synchronized (target) { - target.setDeploymentManifest(new DeploymentManifest( - target.getDeploymentManifest(), - null, - target.isAutostart(), - target.getSubsystemId(), - SubsystemIdentifier.getLastId(), - target.getLocation(), - false, - false)); + finally { + // Release the read lock. + LockingStrategy.readUnlock(); } } - catch (Exception e) { - throw new SubsystemException(e); + finally { + // Protection against re-entry no longer required. + LockingStrategy.unset(State.STOPPING, target); } return null; } Modified: aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResource.java URL: http://svn.apache.org/viewvc/aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResource.java?rev=1738981&r1=1738980&r2=1738981&view=diff ============================================================================== --- aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResource.java (original) +++ aries/branches/java6support/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResource.java Wed Apr 13 18:41:23 2016 @@ -87,18 +87,18 @@ public class SubsystemResource implement private final Collection<Resource> sharedContent = new HashSet<Resource>(); private final Collection<Resource> sharedDependencies = new HashSet<Resource>(); - public SubsystemResource(String location, IDirectory content, BasicSubsystem parent) throws URISyntaxException, IOException, ResolutionException, BundleException, InvalidSyntaxException { - this(new RawSubsystemResource(location, content, parent), parent); + public SubsystemResource(String location, IDirectory content, BasicSubsystem parent, Coordination coordination) throws URISyntaxException, IOException, ResolutionException, BundleException, InvalidSyntaxException { + this(new RawSubsystemResource(location, content, parent), parent, coordination); } - public SubsystemResource(RawSubsystemResource resource, BasicSubsystem parent) throws IOException, BundleException, InvalidSyntaxException, URISyntaxException { + public SubsystemResource(RawSubsystemResource resource, BasicSubsystem parent, Coordination coordination) throws IOException, BundleException, InvalidSyntaxException, URISyntaxException { this.parent = parent; this.resource = resource; computeContentResources(resource.getDeploymentManifest()); capabilities = computeCapabilities(); if (this.getSubsystemManifest().getSubsystemTypeHeader().getAriesProvisionDependenciesDirective().isInstall()) { /* compute dependencies now only if we intend to provision them during install */ - computeDependencies(resource.getDeploymentManifest()); + computeDependencies(resource.getDeploymentManifest(), coordination); } deploymentManifest = computeDeploymentManifest(); } @@ -122,7 +122,7 @@ public class SubsystemResource implement capabilities = computeCapabilities(); if (getSubsystemManifest().getSubsystemTypeHeader().getAriesProvisionDependenciesDirective().isInstall()) { /* compute dependencies if we intend to provision them during install */ - computeDependencies(resource.getDeploymentManifest()); + computeDependencies(resource.getDeploymentManifest(), null); } } @@ -367,9 +367,9 @@ public class SubsystemResource implement } } - void computeDependencies(DeploymentManifest manifest) { + void computeDependencies(DeploymentManifest manifest, Coordination coordination) { if (manifest == null) { - computeDependencies(getSubsystemManifest()); + computeDependencies(getSubsystemManifest(), coordination); } else { ProvisionResourceHeader header = manifest.getProvisionResourceHeader(); @@ -384,9 +384,13 @@ public class SubsystemResource implement } } - private void computeDependencies(SubsystemManifest manifest) { + private void computeDependencies(SubsystemManifest manifest, Coordination coordination) { SubsystemContentHeader contentHeader = manifest.getSubsystemContentHeader(); try { + // The following line is necessary in order to ensure that the + // export sharing policies of composites are in place for capability + // validation. + StartAction.setExportPolicyOfAllInstallingSubsystemsWithProvisionDependenciesResolve(coordination); Map<Resource, List<Wire>> resolution = Activator.getInstance().getResolver().resolve(createResolveContext()); setImportIsolationPolicy(resolution); for (Map.Entry<Resource, List<Wire>> entry : resolution.entrySet()) {
