Re: [osgi-dev] Retrieving service configuration implementation in reference method

2018-09-03 Thread Alain Picard via osgi-dev
On Mon, Sep 3, 2018 at 9:27 AM Tim Ward  wrote:

>
>
> On 3 Sep 2018, at 12:46, Alain Picard  wrote:
>
> Tim,
>
> Regarding point 1, I feel like I dropped the ball and it makes sense.
>
>
> Not really, there genuinely is a bug in bnd 4.0, and it was only fixed in
> the 4.1 development stream recently (within the last week).
>
>
> 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
> 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.
>
>
> This is not a bug. Classes are “difficult” types as they cannot be easily
> loaded without knowing the module that should provide them. This is one of
> the many reasons that class names are discouraged throughout OSGi. In this
> case the service property that you’re trying to convert is a String class
> name, and the Converter is trying to load that class using its own class
> loader (it doesn’t have any other options). In Java EE they use the Thread
> Context ClassLoader as a hack to get around this, setting that to the
> “correct” ClassLoader to use when trying to load types from the application
> in server runtime code.
>
> You have several options to work around this.
>
>
>1. Your best option is not to use a class name as a service property
>at all, and avoid using the Class object. Reflectively loading classes is
>the beginning of much pain in OSGi, and using a different solution usually
>results in much better overall modularity.
>
> A bit of the chicken and egg problem. In converting from Eclipse extension
point I went from a "type safe" (at least tooling checked) class name in
plugin.xml to a string property that is unchecked and won't be auto-renamed
if changed. This solution attempts to address the issue of avoiding to use
a string.

>
>1. If you really do need access to the Class (why?) then return it
>from a method on the service so that it can be loaded by a bundle who knows
>how and where to load it from. This still leaves you with potential issues,
>but should be workable
>
> Why? Since I'm using a 3rd party library that pretty much expects it that
way and some legacy layers.

>
>1. Add a custom rule to your converter instance that uses the
>“correct” bundle class loader to load the class. This may be your own
>(potential for missing imports) the bundle that registered the service
>(potential for missing uses) or some other bundle (good luck finding it)!.
>
> I am thinking that here I can just simply do props.get("tester.class");
and get the full class name and call our code that already replicates the
behavior used for extension point to createExecutableExtension and that
calls bundle.loadClass. I then get the type safety at dev time, and I can
always manage the loading at runtime.

Thanks
Alain

>
> Best Regards,
>
> Tim
>
>
> Thanks
> Alain
>
>
> On Mon, Sep 3, 2018 at 6:12 AM Tim Ward  wrote:
>
>>
>> Problem 1:
>>
>> The Relevant bitts of the specification are:
>>
>> How component properties 

Re: [osgi-dev] Retrieving service configuration implementation in reference method

2018-09-03 Thread Tim Ward via osgi-dev


> On 3 Sep 2018, at 12:46, Alain Picard  wrote:
> 
> Tim,
> 
> Regarding point 1, I feel like I dropped the ball and it makes sense. 

Not really, there genuinely is a bug in bnd 4.0, and it was only fixed in the 
4.1 development stream recently (within the last week).

> 
> 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 
> 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.

This is not a bug. Classes are “difficult” types as they cannot be easily 
loaded without knowing the module that should provide them. This is one of the 
many reasons that class names are discouraged throughout OSGi. In this case the 
service property that you’re trying to convert is a String class name, and the 
Converter is trying to load that class using its own class loader (it doesn’t 
have any other options). In Java EE they use the Thread Context ClassLoader as 
a hack to get around this, setting that to the “correct” ClassLoader to use 
when trying to load types from the application in server runtime code.

You have several options to work around this.

Your best option is not to use a class name as a service property at all, and 
avoid using the Class object. Reflectively loading classes is the beginning of 
much pain in OSGi, and using a different solution usually results in much 
better overall modularity.
If you really do need access to the Class (why?) then return it from a method 
on the service so that it can be loaded by a bundle who knows how and where to 
load it from. This still leaves you with potential issues, but should be 
workable
Add a custom rule to your converter instance that uses the “correct” bundle 
class loader to load the class. This may be your own (potential for missing 
imports) the bundle that registered the service (potential for missing uses) or 
some other bundle (good luck finding it)!.

Best Regards,

Tim

> 
> Thanks
> Alain
> 
> 
> On Mon, Sep 3, 2018 at 6:12 AM Tim Ward  > 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 
>  to make sure that this was done 
> correctly.
> 
> 
> 

Re: [osgi-dev] Retrieving service configuration implementation in reference method

2018-09-03 Thread Alain Picard via osgi-dev
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
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  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
>  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  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  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 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 

Re: [osgi-dev] Retrieving service configuration implementation in reference method

2018-09-03 Thread Tim Ward via osgi-dev

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 
 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  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  > 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 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 > > 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
>> 

Re: [osgi-dev] Retrieving service configuration implementation in reference method

2018-08-25 Thread Alain Picard via osgi-dev
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  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 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  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  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  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 

Re: [osgi-dev] Retrieving service configuration implementation in reference method

2018-08-24 Thread Alain Picard via osgi-dev
Tim,

I didn't do this here since has you might have noticed this is a factory
and the evaluation (your getRendereFor) is to determine which renderer type
to get a new instance of. We are using the pattern that you describe where
the services are just selected. But maybe it's just a piece that I'm
missing and it's a simple change.

Alain

On Fri, Aug 24, 2018 at 5:52 AM Tim Ward  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 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  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  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  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  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 

Re: [osgi-dev] Retrieving service configuration implementation in reference method

2018-08-24 Thread Tim Ward via osgi-dev
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 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  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  > 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 > > 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 > > 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 

Re: [osgi-dev] Retrieving service configuration implementation in reference method

2018-08-24 Thread Alain Picard via osgi-dev
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  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  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  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
>>
>>
>

Re: [osgi-dev] Retrieving service configuration implementation in reference method

2018-08-24 Thread Tim Ward via osgi-dev
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  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  > 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  > > 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 
> > 
> 

___
OSGi Developer Mail List
osgi-dev@mail.osgi.org
https://mail.osgi.org/mailman/listinfo/osgi-dev

Re: [osgi-dev] Retrieving service configuration implementation in reference method

2018-08-24 Thread Alain Picard via osgi-dev
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  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
>
>
___
OSGi Developer Mail List
osgi-dev@mail.osgi.org
https://mail.osgi.org/mailman/listinfo/osgi-dev

Re: [osgi-dev] Retrieving service configuration implementation in reference method

2018-08-23 Thread Tim Ward via osgi-dev
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  
> 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

___
OSGi Developer Mail List
osgi-dev@mail.osgi.org
https://mail.osgi.org/mailman/listinfo/osgi-dev

[osgi-dev] Retrieving service configuration implementation in reference method

2018-08-22 Thread Alain Picard via osgi-dev
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