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.