Problem 1:

The Relevant bitts of the specification are:

How component properties override each other at runtime:
https://osgi.org/specification/osgi.cmpn/7.0.0/service.component.html#service.component-component.properties
 
<https://osgi.org/specification/osgi.cmpn/7.0.0/service.component.html#service.component-component.properties>

How component properties override each other at build time:
https://osgi.org/specification/osgi.cmpn/7.0.0/service.component.html#service.component-ordering.generated.properties
 
<https://osgi.org/specification/osgi.cmpn/7.0.0/service.component.html#service.component-ordering.generated.properties>

The sum total of this is that the component properties from the annotation that 
you’ve applied to your component class should come *after* the ones from the 
activate method. There was a very recent fix in Bnd 
<https://github.com/bndtools/bnd/pull/2595> to make sure that this was done 
correctly.


Problem 2:

As for your additional issue - A component property type is not a valid input 
for method injection with references. See 
https://osgi.org/specification/osgi.cmpn/7.0.0/service.component.html#service.component-method.injection
 
<https://osgi.org/specification/osgi.cmpn/7.0.0/service.component.html#service.component-method.injection>

You can use the OSGi converter to convert an injected map of properties into an 
instance the annotation if you want.

Best Regards,

Tim

> On 25 Aug 2018, at 12:37, Alain Picard <[email protected]> wrote:
> 
> I had an idea to try using @ComponentPropertyType and searched and found that 
> while not specifically covered by the documentation, in the cpmn there is at 
> least one case of a Class property in ExportedService and that the code seems 
> to support it (ComponentPropertyTypeDataCollector#valueToProperty)
> 
> So I went ahead and tried it and it works, but I'm having a more general 
> issue with the ComponentProperty type. I am attaching the test project.
> 
> The encountered issues are twofold. First what is happening is that the 
> values supplied to the annotation are seen in the component, are seen in the 
> reference method of the using service, but not in its activate method, where 
> I get the default values from the annotation. Second, my service that 
> references the one annotated with my component annotation won't start if I 
> use a method signature that references the annotation type instead of using a 
> map. 
> 
> Please enlighten me.
> 
> Alain
> 
> 
> On Fri, Aug 24, 2018 at 5:52 AM Tim Ward <[email protected] 
> <mailto:[email protected]>> wrote:
> Right, so in this case it looks like you’re running a whiteboard, is it 
> possible you would be better off not using the service properties for this 
> filtering? For example:
> 
> @Reference(policy=DYNAMIC, cardinality=MULTIPLE)
> private final List<ZKRenderer> renderers = new CopyOnWriteArrayList<>();
> 
> public ZKRenderer getRendererFor(Object o) {
>     return renderers.stream()
>         .filter(r -> r.supports(o))
>         .collect(Collectors.maxBy((a,b) -> 
> a.getPriority(o).compareTo(b.getPriority(o))))
>         .orElseThrow(() -> new IllegalArgumentException("No renderer for 
> object " + o));
> }
> 
> Tim
> 
>> On 24 Aug 2018, at 10:34, Alain Picard <[email protected] 
>> <mailto:[email protected]>> wrote:
>> 
>> They represent classes, which is why I would have like to have a Class 
>> annotation so I could do "tester=MyTester.class". instead of 
>> "tester="com.acme.mypkg.MyTester". 
>> 
>> For example I have a number of components implementing a service and as part 
>> of their property they define their "filter conditions" which are then 
>> passed on to the 3rd party library, and there are 2 types of testers, etc:
>> Component(service=ZKRenderer.class, factory=ZKRenderer.CONFIG_FACTORY,
>>   property= { ZKRenderer.CONFIG_STATIC_TEST + "=c.c.i.tester.ReferenceTree", 
>>               ZKRenderer.CONFIG_STATIC_TEST_PRIORITY + ":Integer=9" })
>> 
>> If I move my ReferenceTree tester in the above case, no compiler would catch 
>> it and I'm just looking for pain in the future. 
>> 
>> I am not sure I grasp your approach. Here clients just ask for a renderer 
>> (an instance of the service) for some "object" that is passed in and an 
>> appropriate and "highest ranking" one is returned. So the client is never 
>> specifying the class string at all. Here we are providing the full class 
>> name so it can be loaded, hence it would be much more natural to provide a 
>> Class object. 
>> 
>> When we have cases where the component and reference must have to match we 
>> do as such:
>>     public static final String CONFIG_QUALIFIER = 
>> OsgiConstants.SERVICE_QUALIFIER + "=ReferenceList"; //$NON-NLS-1$
>>     public static final String CONFIG_TARGET = "(" + CONFIG_QUALIFIER + ")"; 
>> //$NON-NLS-1$ //$NON-NLS-2$
>> 
>> and here the component use the 1st line in its property and the reference 
>> target uses the 2nd constant and that is not an issue.
>> 
>> Alain
>> 
>> 
>> 
>> Alain Picard
>> Chief Strategy Officer
>> Castor Technologies Inc
>> o:514-360-7208
>> m:813-787-3424
>> 
>> [email protected] <mailto:[email protected]>
>> www.castortech.com <http://www.castortech.com/>
>> 
>> On Fri, Aug 24, 2018 at 5:16 AM Tim Ward <[email protected] 
>> <mailto:[email protected]>> wrote:
>> Do these properties “represent” classes or are they actually classes? If 
>> they are just representations (which would be a good thing) then you can 
>> define a static string constant representing the class which is mapped 
>> internally to the correct class name (which can then change over time). 
>> Clients then filter based on the string representation which will not change.
>> 
>> Tim
>> 
>> 
>>> On 24 Aug 2018, at 10:07, Alain Picard <[email protected] 
>>> <mailto:[email protected]>> wrote:
>>> 
>>> Tim & all,
>>> 
>>> My immediate use case is that my components have some properties and some 
>>> of those represent classes (this interfaces with 3rd party libraries, I 
>>> would probably design it differently if I could, but it has to be 
>>> configuration as it is used to determine if the component is a match, much 
>>> like for target filters). Properties in the component annotation are 
>>> String[] and that forces the specification of classes as String which is 
>>> very bad since if the class is moved, renamed, deleted, etc, it will cause 
>>> no error or warning and blow up later on. And since annotations only 
>>> support compile time constants, you can't do a MyClass.class.getName() to 
>>> even get a String. My idea was since the implementation class is part of 
>>> the component description, if I could get a hold of it, to have a static 
>>> method in the class to provide this "constant".
>>> 
>>> How can I work around the limitations of Properties as String and Java 
>>> compile time constants. Am I stuck to introduce a new separate annotation 
>>> to track this configuration?
>>> 
>>> Alain
>>> 
>>> Alain
>>> 
>>> 
>>> On Thu, Aug 23, 2018 at 5:24 AM Tim Ward <[email protected] 
>>> <mailto:[email protected]>> wrote:
>>> The properties visible in the Map (or ServiceReference) are the service 
>>> properties. There is some overlap with configuration (services that are 
>>> configurable are encouraged to publish configuration properties as service 
>>> properties) but they are separate, and can be different.
>>> 
>>> The only way that something becomes a service property is if it is 
>>> deliberately registered as such or, for a few specific properties such as 
>>> service.id <http://service.id/> and service.scope, added automatically by 
>>> the framework. 
>>> 
>>> The class name of the implementation would only be added as a service 
>>> property if done so deliberately, and this is typically discouraged (it 
>>> leaks internal implementation detail and forces your internal naming to 
>>> become API). If you *really* care about the details of a service (and in 
>>> general you shouldn’t) then you should mark it with a service property that 
>>> you can recognise. Ideally one that is separate from the other 
>>> implementation details of the service.
>>> 
>>> Best Regards,
>>> 
>>> Tim
>>> 
>>> > On 22 Aug 2018, at 16:53, Alain Picard via osgi-dev 
>>> > <[email protected] <mailto:[email protected]>> wrote:
>>> > 
>>> > In a reference method, i can get the property configuration of the 
>>> > service along with the ComponentFactory and some other optional 
>>> > arguments. Can any of those give me a way to retrieve the implementation 
>>> > from the configuration (i.e. the class name of the implementation) ?
>>> > 
>>> > Thanks
>>> > Alain
>>> > 
>>> > _______________________________________________
>>> > OSGi Developer Mail List
>>> > [email protected] <mailto:[email protected]>
>>> > https://mail.osgi.org/mailman/listinfo/osgi-dev 
>>> > <https://mail.osgi.org/mailman/listinfo/osgi-dev>
>>> 
>> 
> 
> <comp.property.test.zip>

_______________________________________________
OSGi Developer Mail List
[email protected]
https://mail.osgi.org/mailman/listinfo/osgi-dev

Reply via email to