Hi,
On 19.04.2009, at 16:45, Guillaume Nodet wrote:
After having experimented a bit with iPojo, I came to the conclusion
that this library is not the best suited for the blueprint spec.
The main reason is that the way it handles a dependency on an OSGi
service is by enhancing/instrumenting the pojo that will be injected.
While this works very well, it is quite problematic for implementing
the blueprint spec, as this spec clearly mandates the creation of a
proxy that will later be injected.
I definitely agree. I just read the spec (nice weekend reading :-)),
and for sure it is built on dynamic proxies. From the other side,
iPOJO was made to avoid the injection of proxies. When it's required,
it uses generated "smart" proxies (to reduce the performance cost).
Furthermore, a few geronimo committers were interested in implementing
this spec too, so I've started working with them there (as I am a
Geronimo committer):
https://svn.apache.org/repos/asf/geronimo/sandbox/blueprint/
I think the code should be moved into Felix at some point, but it's
easier to develop there for Geronimo committers. I'll keep you
posted.
Yep, definitely interesting. Felix sounds like the good location to
host it.
Regards,
Clement
On Mon, Apr 13, 2009 at 11:52, Clement Escoffier
<clement.escoff...@gmail.com> wrote:
On 13.04.2009, at 11:20, Guillaume Nodet wrote:
On Mon, Apr 13, 2009 at 11:15, Clement Escoffier
<clement.escoff...@gmail.com> wrote:
On 13.04.2009, at 11:01, Guillaume Nodet 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.
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">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 ?
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
--
Cheers,
Guillaume Nodet
------------------------
Blog: http://gnodet.blogspot.com/
------------------------
Open Source SOA
http://fusesource.com