On Mon, Apr 13, 2009 at 11:01, Guillaume Nodet <gno...@gmail.com> wrote: > On Mon, Apr 13, 2009 at 10:03, Clement Escoffier > <clement.escoff...@gmail.com> wrote: >> Hi ! >> On 12.04.2009, at 22:06, Guillaume Nodet wrote: >> >>> I'm investigating implementing the blueprint spec on top of iPojo, but >>> after digging a bit in the iPojo code, I have a few questions. >> >> Nice investigation ;-) >> >>> >>> * constructor injection seems to be missing >> >> True, I' m not a fan of constructor injection. However, if it's a "must", I >> will add it. >> Service will be injected by using temporal dependencies (with or without >> proxies). >> >>> >>> * not sure how to inject other components as properties of a given >>> component. It seems properties can only handle simple types, while >>> dependencies require interfaces >> >> About properties : primitives and objects are supported, as well as lists, >> dictionaries and maps of objects. To inject an object, either you create the >> object and add it to the instance configuration (so, must use the iPOJO >> api), or you have a type with a String constructor (in this case, the >> property can be declared in the metadata.xml file). >> So, you can inject instance with properties. But, properties are not >> intended to impact the lifecycle. However, when you inject an instance, and >> if this instance is invalid, the instance using the invalid instance should >> be invalid too. >> >> About services: I recently remove the 'interface' limitation. This is >> available is the trunk version (and so will be available in the 1.4.0 >> version). > > Yes, I've seen that. I've been able to programmatically wire two > simple pojos together. > However I hit an issue: when using the programmatic api, the class is > manipulated and the class is actually not the same than the one which > is loaded by default from the bundle. When exporting this service in > the OSGi registry, this means that the object actually exported is not > compatible with the class that other bundles can see (which is the > default one provided by the bundle). > This means you can't really do the manipulation at runtime. Is there > a way to disable the bytecode manipulation ? I think this should be > possible for the blueprint spec because field injection is not really > supported by the blueprint spec and everything is done using > constructor or setter injection.
Following is a code snippet I use to reproduce the problem: MyInstanceCreator creator = new MyInstanceCreator(bundleContext); PrimitiveComponentType pojoB = new PrimitiveComponentType() .setBundleContext(bundleContext) .setComponentTypeName("PojoB") .setClassName(PojoB.class.getName()) .addDependency(new Dependency() .setBindMethod("setPojoA") .setNullable(false) .setOptional(false)); creator.addFactory((IPojoFactory) pojoB.getFactory()); PrimitiveComponentType pojoA = new PrimitiveComponentType() .setBundleContext(bundleContext) .setComponentTypeName("PojoA") .setClassName(PojoA.class.getName()) .setValidateMethod("start") .setInvalidateMethod("stop") .addService(new Service() .setSpecification(PojoA.class.getName())); creator.addFactory((IPojoFactory) pojoA.getFactory()); creator.addInstance("PojoA"); creator.addInstance("PojoB"); The behavior is that both instances will be created, but PojoB will be injected a null instance of PojoA because the OSGi registry check class compatibility and the expected PojoA class is not the one received (which is a manipulated version of PojoA). >>> >>> * ability to create and populate collections to inject as properties >>> (only collections of simple types are supported afaik) >> >> List, vector, map and dictionary of any type (as well as maps of lists of >> dictionaries of vectors) are supported. > > Yes, but I haven't seen any way to create and populate complex > collections: i.e. a collection that contains a list of components for > example, or even a collection containing a string and an integer > value. > > For example, look at the following example from the spec: > > <component id="moreComplexObject" class="example.ComplexObject"> > <!-- results in a setAdminEmails(java.util.Properties) call --> > <property name="adminEmails"> > <props> > <prop key="administrator">administra...@example.org</prop> > <prop key="support">supp...@example.org</prop> > <prop key="development">developm...@example.org</prop> > </props> > </property> > <!-- results in a setSomeList(java.util.List) call --> > <property name="someList"> > <list> > <value>a list element followed by a reference</value> > <ref component="myDataSource" /> > </list> > </property> > <!-- results in a setSomeMap(java.util.Map) call --> > <property name="someMap"> > <map> > <entry> > <key> > <value>an entry</value> > </key> > <value>just some string</value> > </entry> > <entry> > <key> > <value>a ref</value> > </key> > <ref component="myDataSource" /> > </entry> > </map> > </property> > <!-- results in a setSomeSet(java.util.Set) call --> > <property name="someSet"> > <set> > <value>just some string</value> > <ref component="myDataSource" /> > </set> > </property> > </component> > > How can I create the above collections which have simple values and > components inside ? > >>> >>> * ability to expose classes and not only interfaces in the osgi registry >> >> As said above, this was recently fixed. >> >>> >>> * when manipulating the bytecode to enhance the classes, can iPojo >>> handle the parent classes ? i.e. if a field is defined in the parent >>> class, will iPojo manipulate it accordingly ? >> >> That's more tricky. iPOJO does not manipulate parent class. The issue is >> that 1) parent classes can be in a different bundle (not iPOJO powered), and >> the parent class can be extended by non iPOJO classes. So, right now, only >> method injection is supported in parent classes. I plan to try to support >> parent manipulation, it's on the roadmap since at least one year and never >> find an adequate time slot). >> >>> >>> On point #2, i think iPojo can only handle dependencies that are >>> imported as OSGi services. If this is true, does this mean I have to >>> create a composite so that all component instances are create at the >>> composite level and not really exported in the OSGi registry ? >> >> I would prefer that way: >> - first instance injection can impact the lifecycle. Service injection >> impacts the lifecyle, so makes sense to use to inject instances. >> - composite brings the isolation property that is also promoted by the >> blueprint. Only beans of the same application context can be injected. In >> iPOJO terms, it would be : services from the same composite (i.e. service >> context) can be injected. >> > > Yes, that makes sense to me. > >>> >>> The blueprint spec mostly rely on component dependency injection where >>> components are instanciated and wired explicitely. How can I achieve >>> that using iPojo ? >> >> Inside composites, it's possible. Instances are declared with: >> <composite> >> <instance .../> >> ... >> </composite> >> >> I will commit the API allowing to declare composites "programmatically". > > Cool, that should help a lot. > >> If you rely on the composite service registry to bound instances together, >> you can provide all the Blueprint features. >> >> Regards, >> >> Clement >> >> >>> >>> >>> -- >>> Cheers, >>> Guillaume Nodet >>> ------------------------ >>> Blog: http://gnodet.blogspot.com/ >>> ------------------------ >>> Open Source SOA >>> http://fusesource.com >> >> > > > > -- > Cheers, > Guillaume Nodet > ------------------------ > Blog: http://gnodet.blogspot.com/ > ------------------------ > Open Source SOA > http://fusesource.com > -- Cheers, Guillaume Nodet ------------------------ Blog: http://gnodet.blogspot.com/ ------------------------ Open Source SOA http://fusesource.com