Well, it supports it with sub-typing as Ray shows. This is perfectly type safe
and does not require tricks.
To support this in the API, we would need a TypeReference class that would be
subclassed (I guess this what you mean with the supertype token pattern?).
new TypeReference<Map<String,String>>() {}
The TypeReference has a getGenericType method that returns the type information
of the super class. The OSGi API would have to recognize this (sub) class and
then carry the generic type information.
registerService( TypeReference<T> tref, T t, Map<String,Object> props );
registerService( new TypeReference<Map<String,String>>() {}, new
HashMap<String,String>(), null );
And then on ServiceReference<?>
Type getGenericType()
And for the queries
List<ServiceReference<T>> getServiceReferences( TypeReference<T> ref,
String filter );
Guess this would actually be relatively easy to do. I guess the raw type can
always provide backward compatibility, though are probably some nasty corner
cases lurking.
Extension for R7?
Kind regards,
Peter Kriens
> On 18 mrt. 2015, at 19:16, elias vasylenko <[email protected]> wrote:
>
> 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" <[email protected]
> <mailto:[email protected]>> 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 <[email protected]
> <mailto:[email protected]>> wrote:
> [email protected] <mailto:[email protected]> wrote
> on 2015/03/18 09:04:08:
>
> > From: Frank Langel <[email protected] <mailto:[email protected]>>
> > 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/>
> [email protected] <mailto:[email protected]>
>
> office: +1 386 848 1781 <tel:%2B1%20386%20848%201781>
> mobile: +1 386 848 3788 <tel:%2B1%20386%20848%203788>
>
>
>
> _______________________________________________
> 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>
>
>
>
> --
> 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
> [email protected] <mailto:[email protected]>
> https://mail.osgi.org/mailman/listinfo/osgi-dev
> <https://mail.osgi.org/mailman/listinfo/osgi-dev>
> _______________________________________________
> OSGi Developer Mail List
> [email protected]
> https://mail.osgi.org/mailman/listinfo/osgi-dev
_______________________________________________
OSGi Developer Mail List
[email protected]
https://mail.osgi.org/mailman/listinfo/osgi-dev