users@hk2.java.net

Re: Injecting Type Variable Fields

From: Mirko Raner <mirko.raner_at_lab49.com>
Date: Mon, 8 Jun 2015 23:30:58 -0400

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.