Tim,

Regarding point 1, I feel like I dropped the ball and it makes sense.

Regarding point 2, I learned something about the use of converters to
manage component property types (and not to use them anywhere). So I read
in chapter 707 to find out how to do it and now I have an issue with my
Class method, which throws an exception. The priority which is an integer
works fine.

Code:
    @Reference
    private void addRenderer(ConfiguredComponent scc, Map<String,Object>
props) {
        this.scc = scc;
        Converter converter = Converters.standardConverter();
        RendererConfig config =
converter.convert(props).to(RendererConfig.class);

        System.out.println("Adding renderer with Tester priority:" +
config.tester_priority() + "full props" + props);
        System.out.println("Tester:" + config.tester_class());
    }

And the exception is:
java.lang.NoClassDefFoundError: comp.property.test.RendererFactory
    at
org.osgi.util.converter.ConverterImpl.loadClassUnchecked(ConverterImpl.java:352)
    at
org.osgi.util.converter.ConverterImpl$19.apply(ConverterImpl.java:157)
    at
org.osgi.util.converter.ConverterImpl$19.apply(ConverterImpl.java:154)
    at org.osgi.util.converter.Rule$1.apply(Rule.java:67)
    at
org.osgi.util.converter.CustomConverterImpl$ConvertingWrapper.to(CustomConverterImpl.java:162)
    at
org.osgi.util.converter.ConvertingImpl$4.invoke(ConvertingImpl.java:809)
    at com.sun.proxy.$Proxy3.tester_class(Unknown Source)
    at
comp.property.test.RendererFactory.addRenderer(RendererFactory.java:23)

And the "swallowed exception is:
java.lang.ClassNotFoundException: comp.property.test.RendererFactory not
found by org.osgi.util.converter [6]
org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1597)
org.apache.felix.framework.BundleWiringImpl.access$300(BundleWiringImpl.java:79)
org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1982)
java.lang.ClassLoader.loadClass(Unknown Source)
org.osgi.util.converter.ConverterImpl.loadClassUnchecked(ConverterImpl.java:350)

any idea or is this is bug or a what.

Thanks
Alain


On Mon, Sep 3, 2018 at 6:12 AM Tim Ward <tim.w...@paremus.com> wrote:

>
> 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
>
> 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
>
> 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
>
> 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 <pic...@castortech.com> 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 <tim.w...@paremus.com> 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 <pic...@castortech.com> 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
>>
>> pic...@castortech.com
>> www.castortech.com
>>
>>
>> On Fri, Aug 24, 2018 at 5:16 AM Tim Ward <tim.w...@paremus.com> 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 <pic...@castortech.com> 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 <tim.w...@paremus.com> 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 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 <
>>>> osgi-dev@mail.osgi.org> 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
>>>> > osgi-dev@mail.osgi.org
>>>> > https://mail.osgi.org/mailman/listinfo/osgi-dev
>>>>
>>>>
>>>
>> <comp.property.test.zip>
>
>
>
_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org
https://mail.osgi.org/mailman/listinfo/osgi-dev

Reply via email to