users@hk2.java.net

Re: Injecting Type Variable Fields

From: Mirko Raner <mirko.raner_at_lab49.com>
Date: Wed, 10 Jun 2015 21:40:13 -0400

Was anyone able to reproduce this issue? I tried with HK2 2.4.0-b25 and got
the same exception.
Is there maybe something wrong with my bindings?
I tried a similar example with Guice, and the type variable was injected
correctly, as expected.

On Mon, Jun 8, 2015 at 11:30 PM, Mirko Raner <mirko.raner_at_lab49.com> wrote:

> I can't share the original code, as it belongs to the client, but the code
> below should be fairly close:
>
> import java.util.HashMap;
>
> import java.util.Map;
>
> import java.util.stream.StreamSupport;
>
> import javax.annotation.PostConstruct;
>
> import javax.inject.Inject;
>
> import javax.inject.Singleton;
>
> import org.glassfish.hk2.api.IterableProvider;
>
> import org.glassfish.hk2.api.ServiceLocator;
>
> import org.glassfish.hk2.utilities.ServiceLocatorUtilities;
>
> import org.glassfish.hk2.utilities.binding.AbstractBinder;
>
> import org.jvnet.hk2.annotations.Contract;
>
> import org.jvnet.hk2.annotations.Service;
>
> import static java.util.function.Function.identity;
>
> import static java.util.stream.Collectors.toMap;
>
>
> @Singleton
>
> class MessageDispatcher {
>
> private Map<String, MessageHandler<?>> dispatch;
>
> @Inject IterableProvider<MessageHandler<?>> handlers;
>
> @PostConstruct void buildDispatch() {
>
> dispatch = StreamSupport.stream(handlers.spliterator(), false).collect(toMap(MessageHandler::getMessageType,
> identity()));
>
> }
>
> void process(Map<String, String> message) {
>
> dispatch.get(message.get("type")).handle(message);
>
> }
>
> }
>
>
> @Contract
>
> abstract class MessageHandler<T> {
>
> @Inject T translator;
>
> abstract void handle(Map<String, String> message);
>
> abstract String getMessageType();
>
> }
>
>
> @Service
>
> class GetMessageHandler extends MessageHandler<GetTranslator> {
>
> @Override void handle(Map<String, String> message) {
>
> Get get = translator.translate(message.get("key"));
>
> System.err.println(get);
>
> }
>
> @Override String getMessageType() {
>
> return "get";
>
> }
>
> }
>
>
> @Service
>
> class PutMessageHandler extends MessageHandler<PutTranslator> {
>
> @Override void handle(Map<String, String> message) {
>
> Put put = translator.translate(message.get("key"), message.get(
> "value"));
>
> System.err.println(put);
>
> }
>
> @Override String getMessageType() {
>
> return "put";
>
> }
>
> }
>
>
> class Get { Get(String key) {}}
>
> class Put { Put(String key, String value) {}}
>
>
> class GetTranslator {
>
> Get translate(String key) {
>
> return new Get(key);
>
> }
>
> }
>
>
> class PutTranslator {
>
> Put translate(String key, String value) {
>
> return new Put(key, value);
>
> }
>
> }
>
>
> class HK2Main {
>
> public static void main(String[] arguments) {
>
> AbstractBinder binder = new AbstractBinder() {
>
> @Override
>
> protected void configure() {
>
> addActiveDescriptor(MessageDispatcher.class);
>
> addActiveDescriptor(GetMessageHandler.class);
>
> addActiveDescriptor(PutMessageHandler.class);
>
> addActiveDescriptor(GetTranslator.class);
>
> addActiveDescriptor(PutTranslator.class);
>
> }
>
> };
>
> ServiceLocator serviceLocator = ServiceLocatorUtilities.bind(
> binder);
>
> MessageDispatcher dispatcher = serviceLocator
> .getService(MessageDispatcher.class);
>
> Map<String, String> get = new HashMap<>();
>
> get.put("type", "get");
>
> get.put("key", "KEY");
>
> Map<String, String> put = new HashMap<>();
>
> put.put("type", "put");
>
> put.put("key", "KEY");
>
> put.put("value", "VALUE");
>
> dispatcher.process(get);
>
> dispatcher.process(put);
>
> }
>
> }
>
> On Mon, Jun 8, 2015 at 5:40 PM, john wells <john.wells_at_oracle.com> wrote:
>
>> I'd have to see the exact code where you were binding the services. I am
>> also surprised that this does not work.
>>
>>
>> On 6/8/2015 4:24 PM, Mirko Raner wrote:
>>
>>> Hi all,
>>>
>>> I have a hierarchy of message handlers, where each concrete message
>>> handler needs a specific message translator injected (following DDD
>>> principles):
>>>
>>> abstract class MessageHandler<T> {
>>> @Inject
>>> protected T translator;
>>>
>>> abstract void handle(Object object);
>>> }
>>>
>>> class MyMessageHandler extends MessageHandler<MyTranslator> {
>>> void handle(Object object) {
>>> DomainObject domainObject = translator.translate(object);
>>> }
>>> }
>>>
>>> I would expect that HK2 would be able to resolve this injection,
>>> because, when injecting into MyMessageHandler, T is already bound to
>>> MyTranslator. However, I get the exception "Invalid injectee with required
>>> type of T passed to getInjecteeDescriptor".
>>> The handlers, as well as the translators, are all bound via
>>> addActiveDescriptor(...).
>>>
>>> Am I missing something here? Is this just a limitation of HK2's current
>>> resolution mechanism, or is there some conceptual problem here?
>>>
>>> Thanks for clarifying,
>>>
>>> Mirko
>>>
>>>
>>
>

-- 
 
This email and any attachments may contain information which is 
confidential and/or privileged. The information is intended exclusively for 
the addressee and the views expressed may not be official policy, but the 
personal views of the originator. If you are not the intended recipient, be 
aware that any disclosure, copying, distribution or use of the contents is 
prohibited. If you have received this email and any file transmitted with 
it in error, please notify the sender by telephone or return email 
immediately and delete the material from your computer. Internet 
communications are not secure and Lab49 is not responsible for their abuse 
by third parties, nor for any alteration or corruption in transmission, nor 
for any damage or loss caused by any virus or other defect. Lab49 accepts 
no liability or responsibility arising out of or in any way connected to 
this email.