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