I've been chasing this one around for a while, so I thought it time to ask. :)

I have an Adapter service with one implementation OBRAdapter. I can create 
instances of the OBRAdaptor without difficulty using the following metadata.xml

<ipojo>
        <instance component="com.itslm.omneity.adapter.obr.OBRAdapter">
                <property name="scheme" value="obr1"/>
        </instance>
        <instance component="com.itslm.omneity.adapter.obr.OBRAdapter">
                <property name="scheme" value="obr2"/>
        </instance>
</ipojo>

Now, although these are 'system supplied' Adapters I want to isolate  Adapters 
inside a data management component so that user supplied 'plugins' (that will 
be picked up programmatically later) have limited access to the rest of the 
system. So I created a composite using the following metadata.xml on a 
substantially empty jar (with only bundle identity, basically):

<ipojo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
        xsi:schemaLocation="org.apache.felix.ipojo 
http://felix.apache.org/ipojo/schemas/SNAPSHOT/core.xsd 
            org.apache.felix.composite 
http://felix.apache.org/ipojo/schemas/SNAPSHOT/composite.xsd";
        xmlns="org.apache.felix.ipojo" 
xmlns:comp="org.apache.felix.ipojo.composite">

        <comp:composite name="DataSourceManager">
                <comp:instance 
component="com.itslm.omneity.data.service.DataSourceManagerImpl" />
                <comp:provides action="export"
                        
specification="com.itslm.omneity.data.api.DataSourceManager" />

                <!-- Will programmatically identify and load Adaptor plugins, 
this next 
                        entry imports Adapters in the global scope (so, only 
those that are in the 
                        main bundle directory) 
                        -->
                <comp:subservice action="import" aggregate="true"
                        specification="com.itslm.omneity.adapter.api.Adapter" />

                <comp:subservice action="import"
                        specification="org.osgi.service.log.LogService" />

        </comp:composite>

        <comp:instance component="DataSourceManager" name="DataSourceManager" />

</ipojo>

When I examine the running system I see the two Adapters apparently 
instantiated and available inside the DataSourceManager component (as I hoped).

g! instance DataSourceManager
instance name="DataSourceManager" state="valid" bundle="38" 
component.type="DataSourceManager"
        handler name="org.apache.felix.ipojo:instance" state="valid"
                instance 
factory="com.itslm.omneity.data.service.DataSourceManagerImpl" 
name="com.itslm.omneity.data.service.DataSourceManagerImpl-0" state="valid"
        handler name="org.apache.felix.ipojo:provides" state="valid"
                exports 
specification="com.itslm.omneity.data.api.DataSourceManager" 
filter="(objectClass=com.itslm.omneity.data.api.DataSourceManager)" 
state="resolved"
        handler name="org.apache.felix.ipojo:subservice" state="valid"
                requires specification="com.itslm.omneity.adapter.api.Adapter" 
filter="(&(objectClass=com.itslm.omneity.adapter.api.Adapter)(!(instance.name=DataSourceManager)))"
 state="resolved"
                        provider 
name="com.itslm.omneity.adapter.obr.OBRAdapter-0"
                        provider 
name="com.itslm.omneity.adapter.obr.OBRAdapter-1"
                requires specification="org.osgi.service.log.LogService" 
filter="(&(objectClass=org.osgi.service.log.LogService)(!(instance.name=DataSourceManager)))"
 state="resolved"
                        provider name="null"
        handler name="org.apache.felix.ipojo:architecture" state="valid"
        services
                service 
architecture.instance="com.itslm.omneity.data.service.DataSourceManagerImpl-0" 
factory.name="architecture" instance.name="architecture-6" 
objectclass="[org.apache.felix.ipojo.architecture.Architecture]" service.id="4"
                service 
factory.name="com.itslm.omneity.data.service.DataSourceManagerImpl" 
instance.name="com.itslm.omneity.data.service.DataSourceManagerImpl-0" 
objectclass="[com.itslm.omneity.data.api.DataSourceManager, 
com.tinkerpop.blueprints.TransactionalGraph, 
com.tinkerpop.blueprints.KeyIndexableGraph, 
com.tinkerpop.blueprints.IndexableGraph, com.tinkerpop.blueprints.Graph]" 
service.id="5"
                service factory.name="com.itslm.omneity.adapter.obr.OBRAdapter" 
instance.name="com.itslm.omneity.adapter.obr.OBRAdapter-0" 
objectclass="[com.itslm.omneity.adapter.api.Adapter]" scheme="obr" 
service.id="6"
                service factory.name="com.itslm.omneity.adapter.obr.OBRAdapter" 
instance.name="com.itslm.omneity.adapter.obr.OBRAdapter-1" 
objectclass="[com.itslm.omneity.adapter.api.Adapter]" scheme="obr" 
service.id="7"
                service objectclass="[org.osgi.service.log.LogService]" 
service.id="8"
        containedinstances
                instance 
name="com.itslm.omneity.data.service.DataSourceManagerImpl-0" state="valid" 
bundle="36" 
component.type="com.itslm.omneity.data.service.DataSourceManagerImpl"
                        handler name="org.apache.felix.ipojo:requires" 
state="valid"
                                requires 
specification="com.itslm.omneity.adapter.api.Adapter" 
id="com.itslm.omneity.adapter.api.Adapter" optional="true" nullable="true" 
aggregate="true" proxy="false" binding-policy="dynamic" state="resolved"
                        handler name="org.apache.felix.ipojo:callback" 
state="valid"
                        handler name="org.apache.felix.ipojo:provides" 
state="valid"
                                provides 
specifications="[com.itslm.omneity.data.api.DataSourceManager,com.tinkerpop.blueprints.TransactionalGraph,com.tinkerpop.blueprints.KeyIndexableGraph,com.tinkerpop.blueprints.IndexableGraph,com.tinkerpop.blueprints.Graph]"
 state="registered" service.id="5"
                                        property name="factory.name" 
value="com.itslm.omneity.data.service.DataSourceManagerImpl"
                                        property name="instance.name" 
value="com.itslm.omneity.data.service.DataSourceManagerImpl-0"
                                        controller value="true"
                        handler name="org.apache.felix.ipojo:architecture" 
state="valid"
                        object 
name="com.itslm.omneity.data.service.DataSourceManagerImpl@7e266b44"
g! 

However, inside the DataSourceManagerImpl I have a @Requires, e.g.

        /** All of the Adapter services currently available. */
        @Requires(optional = true)
        private Adapter[] adapters;

This does what I expect outside the composite (namely, dynamically tracks the 
currently available adapters), but inside the composite this field is not 
populated (at least not in the start() method where I do a simple 
LOGGER.debug("Adapters found: " + adapters.length) as a test. This reports '2' 
when running outside the composite, but '0' when running inside the composite.
 
I know I'm missing (or misunderstanding) something. Can anyone help by 
explaining where I'm going wrong? Thanks in advance.

Regards,
Mark


Attachment: signature.asc
Description: Message signed with OpenPGP using GPGMail

Reply via email to