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