Just to make it more clear for the sake of the discussion, there is no
reason we couldn't use the supertype token pattern to have a type safe
service registry for generic types, the osgi api just doesn't currently
support it.
On 18 Mar 2015 14:00, "Raymond Auge" <raymond.a...@liferay.com> wrote:

> The only way to retrain generic information at runtime is with a class
> that extends from a generic one without declaring a generic signature
> itself.
>
> For instance:
>
>          class MyMap extends HashMap<Integer, String> {}
>
> The compiler retains the generic information directly in the class. At
> that point you can, at runtime, check if the type has generic arguments and
> obtain what those argument types were.
>
>         Type[] genericInterfaces = clazz.getGenericInterfaces();
>
>         for (Type genericInterface : genericInterfaces) {
>             if (!(genericInterface instanceof ParameterizedType)) {
>                 continue;
>             }
>
>             ParameterizedType parameterizedType =
>                 (ParameterizedType)genericInterface;
>
>             Type rawType = parameterizedType.getRawType();
>
>             ...
>          }
>
>
> However, you still can't register the service using generics:
>
>          context.registerService(Map.class, new MyMap(), null)
>
> But if you need you could technically impose the restriction from the
> other side and ignore any services which don't have retrained generic
> information.
>
> That might make things a little harder for developers to reason about but
> if this is for "personal" use only, then it may do what you want.
>
> - Ray
>
>
> On Wed, Mar 18, 2015 at 9:11 AM, BJ Hargrave <hargr...@us.ibm.com> wrote:
>
>> osgi-dev-boun...@mail.osgi.org wrote on 2015/03/18 09:04:08:
>>
>> > From: Frank Langel <fr...@frankjlangel.com>
>> > Hi,
>> >
>> > I did some research, but didn¹t find a way to register a generic
>> service.
>> > I would like to do sth like this
>> >
>> >    context.registerService(Map<K,V>.class, service, properties), I.e.
>> >    context.registerService(Map<Integer,String>.class, new
>> > HashMap<Integer,String>(), null)
>>
>> 'Map<Integer,String>.class' does not exist at runtime. Only 'Map.class'
>> exists at runtime due to generics erasure. So there is no way to look up a
>> class using generics since they are erased at runtime.
>>
>> >
>> > The injection should then only work if the registered and the injected K
>> > and V are the same. Assuming I only have one service of type Map
>> > registered,
>> >
>> >    @Reference
>> >    public void setMapService(Map<Integer,String> mymap) {
>> >        This.map = my map;
>> >    }
>> >
>> >    Would succeed.
>> >
>> >    The following would fail as V (registered) != V(referenced service)
>> >
>> >    @Reference
>> >    public void setMapService(Map<Integer,Integer> mymap) {
>> >      this.map = mymap;
>> >    }
>> >
>> > As a workaround, I could define K and V as service properties and filter
>> > for them, but that¹s not very elegant and very error prone
>> >
>> > Any feedback would be appreciated
>> > Frank
>>
>>
>> --
>>
>>  *BJ Hargrave*
>> Senior Technical Staff Member, IBM
>> OSGi Fellow and CTO of the *OSGi Alliance* <http://www.osgi.org/>
>> *hargr...@us.ibm.com* <hargr...@us.ibm.com>
>>
>> office: +1 386 848 1781
>> mobile: +1 386 848 3788
>>
>>
>> _______________________________________________
>> OSGi Developer Mail List
>> osgi-dev@mail.osgi.org
>> https://mail.osgi.org/mailman/listinfo/osgi-dev
>>
>
>
>
> --
> *Raymond Augé* <http://www.liferay.com/web/raymond.auge/profile>
>  (@rotty3000)
> Senior Software Architect *Liferay, Inc.* <http://www.liferay.com>
>  (@Liferay)
> Board Member & EEG Co-Chair, OSGi Alliance <http://osgi.org>
> (@OSGiAlliance)
>
> _______________________________________________
> 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

Reply via email to