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.

Reply via email to