felix-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Steven E. Harris (JIRA)" <j...@apache.org>
Subject [jira] Commented: (FELIX-227) iPOJO should allow configuration and service properties to be bound via setter/getter methods, not just via direct fields
Date Mon, 05 Mar 2007 17:43:50 GMT

    [ https://issues.apache.org/jira/browse/FELIX-227?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12478112
] 

Steven E. Harris commented on FELIX-227:
----------------------------------------

I've used Spring, and maybe I missed some of its features, but its dependency injection worked
by way of supplying constructor parameters to or calling methods on my classes, so its interaction
with my class always respected the encapsulation boundary.

When you write, "you don't have to focus on which value a container-managed field has", this
requires one to know which fields are container-managed. Maybe that's what I'm struggling
with. I was trying to take an existing class and use it with iPOJO's property-injected fields,
and I obviously ran into a lot of trouble. If I had started with the assumptions you're describing,
I could have written the class differently.

But consider what would happen if I decided to change which fields should be bound to service
properties. The class itself keeps on compiling just fine, but now it may be broken, failing
to initialize fields no longer managed by the container. It's hard to be comfortable with
this kind of code.

Your "method" attribute on <property> is almost exactly what I was asking for, but I
would expect that the "field" attribute would be mutually exclusive with the "method" attribute.
If I want iPOJO to call on my methods, I probably don't want it actually touching my fields.

However, a few other questions arise:

Should an updated factory-based Configuration still cause an instance to be killed and recreated,
or should you assume that an instance can tolerate being updated dynamically if it requests
these "method" callbacks? Note that DS deactivates and reactivates an factory-created instance
when its Configuration changes. I'm not sure which is the right way to go.

Also, what about constructors? Would these property callbacks be called after the constructor
runs? In my report above, I noted that initializing these bound fields in the constructor
mistakenly overwrites the iPOJO-property-bound values. What I'd prefer is to allow the default
constructor (or one taking a BundleContext) to run, with its fields initialized by the constructor
code, unmolested by iPOJO, and then have the fresh instance be called on with each of its
"method" property callbacks.

> iPOJO should allow configuration and service properties to be bound via setter/getter
methods, not just via direct fields
> -------------------------------------------------------------------------------------------------------------------------
>
>                 Key: FELIX-227
>                 URL: https://issues.apache.org/jira/browse/FELIX-227
>             Project: Felix
>          Issue Type: Improvement
>          Components: iPOJO
>         Environment: Not relevant.
>            Reporter: Steven E. Harris
>
> iPOJO's binding of configuration properties and service properties directly to component
fields causes a few difficult situations that could be eased by optionally binding the reading
and writing to getter and setter methods instead.
> First, consider a component class with invariants that span multiple fields. iPOJO can
change the value of a field without the owning class knowing, depriving it the chance to update
dependent fields that participate in the invariant. Examples include recalculating and caching
an expensive result whenever some input field changes, or validating a changed value and updating
other fields in response.
> Second, at present iPOJO sets the value of bound fields before the component class constructor
runs. If the constructor attempts to initialize some fields, it may be inadvertantly overwriting
the initial values supplied by iPOJO. Writing the constructor to deliberately ignore values
that might be bound by iPOJO flies in the face of the very name of the project: a POJO isn't
supposed to know that it's being silently manipulated like this, and hence a POJO should be
written in standard form: Initialize variables to sane defaults, including constructor parameters,
expecting them to be overwritten later.
> Take for example a class that has two fields, one of which is bound to a configuration
property:
> public class Example {
>   private String bound;
>   private String dependent;
>   public Example() {
>     bound = null;
>     dependent = "empty";
>   }
>   public void setBound(String s) {
>     bound = s;
>     dependent = null == s || 0 == s.length() ? "empty" : "full";
>   }
>   public String getDependent() {
>     return dependent;
>   }
> }
> If written in this manner, the constructor mistakenly overwrites the initial iPOJO-provided
value for "bound" by initializing it to null. But to resist initializing "bound' is also dangerous;
how would one reading this code have any idea that "bound" might get set to a different value
before the constructor runs, or while the instance is live?
> Also, consider that if "bound' changes silently once the instance is live, "dependent"
will fall out of step, as the invariant maintained in setBound() can be violated.
> If iPOJO would allow property binding to optionally work by way of getter and setter
methods, one and a half of these problems could be avoided. The missing half relates to construction.
If we ask iPOJO to defer setting the "initial values" until the constructor completes, we
may have to defer some initialization that would use the values not yet available.
> Trying to write a POJO class that gets manipulated on the sly by iPOJO is proving to
be more tricky than just writing some of the ManagedServiceFactory code myself, as I'm forced
to adjust my would-be POJO service class to deal with these weird initialization and invariant
maintenance problems normally solved by member variable encapsulation. Perhaps we should look
at Spring's example that better acknowledges not just the technical possibilities, but the
logical difficulties in iPOJO's kind of silent injection and manipulation.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


Mime
View raw message