I'm currently playing with HK2 2.5.0-b05 (which is the version used by Jersey 2.24) and I'm unable to perform a specific type of injection. I was able to generalize my issue and I came up with a simple, small test case.
The code is the following:
package com.github.fabriziocucci.test;
import javax.inject.Inject;
import org.glassfish.hk2.api.ServiceLocator;
import org.glassfish.hk2.api.ServiceLocatorFactory;
import org.glassfish.hk2.api.TypeLiteral;
import org.glassfish.hk2.utilities.ServiceLocatorUtilities;
import org.glassfish.hk2.utilities.binding.AbstractBinder;
public class Test {
private static class A<T> {
private final T t;
@Inject
public A(T t) {
this.t = t;
System.out.println(t);
}
}
private static class B {
}
public static void main(String[] args) {
ServiceLocator serviceLocator = ServiceLocatorFactory.getInstance().create(null);
ServiceLocatorUtilities.bind(serviceLocator, new AbstractBinder() {
@Override
protected void configure() {
bind(B.class).to(B.class);
bindAsContract(new TypeLiteral<A<B>>() {}); // <--- ???
}
});
serviceLocator.getService(new TypeLiteral<A<B>>() {}.getType());
}
}
This code leads to the following exception:
Exception in thread "main" MultiException stack 1 of 3
java.lang.IllegalArgumentException: Invalid injectee with required type of T passed to getInjecteeDescriptor
at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetInjecteeDescriptor(ServiceLocatorImpl.java:546)
at org.jvnet.hk2.internal.ServiceLocatorImpl.getInjecteeDescriptor(ServiceLocatorImpl.java:585)
at org.jvnet.hk2.internal.ThreeThirtyResolver.resolve(ThreeThirtyResolver.java:70)
at org.jvnet.hk2.internal.ClazzCreator.resolve(ClazzCreator.java:211)
at org.jvnet.hk2.internal.ClazzCreator.resolveAllDependencies(ClazzCreator.java:228)
at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:357)
at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:471)
at org.jvnet.hk2.internal.PerLookupContext.findOrCreate(PerLookupContext.java:70)
at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2020)
at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:766)
at org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:713)
at com.github.fabriziocucci.test.Test.main(Test.java:39)
MultiException stack 2 of 3
java.lang.IllegalArgumentException: While attempting to resolve the dependencies of com.github.fabriziocucci.test.Test$A errors were found
at org.jvnet.hk2.internal.ClazzCreator.resolveAllDependencies(ClazzCreator.java:246)
at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:357)
at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:471)
at org.jvnet.hk2.internal.PerLookupContext.findOrCreate(PerLookupContext.java:70)
at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2020)
at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:766)
at org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:713)
at com.github.fabriziocucci.test.Test.main(Test.java:39)
MultiException stack 3 of 3
java.lang.IllegalStateException: Unable to perform operation: resolve on com.github.fabriziocucci.test.Test$A
at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:386)
at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:471)
at org.jvnet.hk2.internal.PerLookupContext.findOrCreate(PerLookupContext.java:70)
at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2020)
at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:766)
at org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:713)
at com.github.fabriziocucci.test.Test.main(Test.java:39)
I'm sure there is something wrong with my code but I can't figure out what is it.
I just tried the same test with hk2-2.5.0-b28 and, unless my code contains some subtle mistake, the result is the same.
More updates are likely to follow here.
This new feature for hk2 is now available with version hk2-2.5.0-b29.
You can use bindAsContract as in your example but you can also directly set the Type on an ActiveDescriptor or use the new "asType" in the EDSL like:
Type type = new TypeLiteral<A<B>>() {}.getType();
ActiveDescriptor<?> ad = BuilderHelper.activeLink(A.class).
to(type).
asType(type).build();