Hi all

I have been puzzled recently when using DS Component Property Types by
the following situation (see also FELIX-5404[0]):

@interface Config {
    String[] whitelist default {};
}

public class WhitelistComponent {
    private String[] whitelist;
    @Activate
    void activate(Config config) {
        this.whitelist = config.whitelist(); // throws NullPointerException
    }
}

Hopefully, you agree that this behaviour is unexpected and
undesirable. I certainly did not expect a NullPointerException when
calling "config.whitelist()"; I expected an empty array, as that's the
default value I defined. (I actually believe this behaviour is in
violation of the Java spec, see my comment in FELIX-5404).

After the discussion in FELIX-5404 I did some more reading in the
spec, but I am still not entirely sure if the problem is in the spec
or in the implementation.

When I look at the generated metatype information the XML files
contain the empty array as default value. The Metatype Service Spec
1.3 clearly defines the case of an empty array default values: "[...]
The empty string is significant and must be seen as an empty List or
array if specified as the default for an attribute with a cardinality
that is not equal to zero. [...]" (105.7.1 XML Schema of a Meta Type
Resource).

However, the Declarative Services Spec 1.3 is less clear about empty
array default values. As I read it, an array (default) value must be
represented in the <property> tag's body: "[...] If the value
attribute is not specified, the body of the property element must
contain one or more values. The value of the property is then an array
of the specified type. [...]". However, it mandates that there be one
or more values, thus explicitly excluding the possibility to represent
an empty array. Our tooling seems to omit any <property> tags with an
empty default value. It is unclear to me how an empty array default
value can or should be represented in a component descriptor.

AFAIU the metatype does not factor in when component configurations
are concerned, hence the default value present in the metatype is
irrelevant for this situation.

This leaves two possible places where this behaviour could be fixed:

1. My understanding is wrong and an empty array default value can be
represented in the component descriptor XML. Then I believe we need to
fix our tooling.
2. When Component Property Types are used, the annotation's default
values should be consulted as a last resort (i.e. if no service
property is set). We would need to check whether this is compliant
with the spec, however.

The third option is to accept this oddity and leave the implementation
as-is. However, this would likely confuse users of component property
types and negate some of their benefits (i.e. null checks would still
be necessary, even if default values are used).

Thanks for your thoughts and insights!

Regards
Julian

[0] https://issues.apache.org/jira/browse/FELIX-5404

Reply via email to