felix-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Clement Escoffier <clement.escoff...@gmail.com>
Subject Re: iPojo and Blueprint services
Date Mon, 13 Apr 2009 09:52:00 GMT

On 13.04.2009, at 11:20, Guillaume Nodet wrote:

> On Mon, Apr 13, 2009 at 11:15, Clement Escoffier
> <clement.escoffier@gmail.com> wrote:
>>
>> On 13.04.2009, at 11:01, Guillaume Nodet wrote:
>>
>>> On Mon, Apr 13, 2009 at 10:03, Clement Escoffier
>>> <clement.escoffier@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.
>>
>> Hum, true. The manipulated class is loaded internally.
>> Unfortunately, there is no way to avoid the manipulation, as it is  
>> not only
>> use for field injection but also to tight the object to the  
>> container and to
>> manage the concurrency.
>> So, the online manipulation cannot be used if you're providing  
>> yourself (ie
>> your classname) as a service...
>
> Would it be possible to create a derived class maybe ? this would not
> allow the use of field injection, but I think this is already limited
> if some of the fields are defined in the parent class and blueprint
> does not use field injection, so I don't really care atm ;-)

This will work. Only the POJO object is loaded by the "Factory" (i.e.  
iPOJO) classloader.


>
>
>>>
>>>
>>>>>
>>>>>  * 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">administrator@example.org</prop>
>>>       <prop key="support">support@example.org</prop>
>>>       <prop key="development">development@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 ?
>>
>> Declare the property and populate the value in the instance  
>> configuration.
>> When you create a new instance, create a dictionary (the instance
>> configuration) with the adequate properties:
>> adminEmails -> the Map containing you data
>> someList -> the List containing your data
>> someMap -> The Map containing your data
>> ...
>
> And what about references to other components ? Those values have to
> be wired as dependencies, or even temporal dependencies in some cases
> ...

You can try that:
ComponentInstance ci = ...
Object obj = ((InstanceManager) ci).getPOJOObject();

obj is now the POJO instance.

The issue with this case, is that ci can become invalid. So, obj  
accesses can be weird if ci is invalid.
Proxying obj to check that the instance is valid is one possibility to  
tackle this case.

Regards,

Clement


>
>
>>
>> Regards,
>>
>> Clement
>>
>>>
>>>
>>>>>
>>>>>  * 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


Mime
View raw message