4444import java .lang .reflect .Type ;
4545import java .util .HashSet ;
4646import java .util .List ;
47+ import java .util .Objects ;
4748import java .util .Set ;
4849import java .util .function .Function ;
4950
@@ -100,14 +101,8 @@ protected void configure() {
100101 @ Inject
101102 private ServiceLocator serviceLocator ;
102103
103- private final Cache <Injectee , ActiveDescriptor <?>> descriptorCache
104- = new Cache <Injectee , ActiveDescriptor <?>>(new Function <Injectee , ActiveDescriptor <?>>() {
105-
106- @ Override
107- public ActiveDescriptor <?> apply (Injectee key ) {
108- return serviceLocator .getInjecteeDescriptor (key );
109- }
110- });
104+ private final Cache <CacheKey , ActiveDescriptor <?>> descriptorCache
105+ = new Cache <>(cacheKey -> serviceLocator .getInjecteeDescriptor (cacheKey .injectee ));
111106
112107 @ Override
113108 public Object resolve (Injectee injectee , ServiceHandle <?> root ) {
@@ -118,10 +113,10 @@ public Object resolve(Injectee injectee, ServiceHandle<?> root) {
118113 if (isHk2Factory ) {
119114 newInjectee = getFactoryInjectee (injectee , ReflectionHelper .getTypeArgument (requiredType , 0 ));
120115 } else {
121- newInjectee = foreignRequestScopedInjecteeCache .apply (injectee );
116+ newInjectee = foreignRequestScopedInjecteeCache .apply (new CacheKey ( injectee ) );
122117 }
123118
124- ActiveDescriptor <?> ad = descriptorCache .apply (newInjectee );
119+ ActiveDescriptor <?> ad = descriptorCache .apply (new CacheKey ( newInjectee ) );
125120
126121 if (ad != null ) {
127122 final ServiceHandle handle = serviceLocator .getServiceHandle (ad , newInjectee );
@@ -144,6 +139,13 @@ public Object resolve(Injectee injectee, ServiceHandle<?> root) {
144139 */
145140 @ Override
146141 public Object resolve (org .glassfish .jersey .internal .inject .Injectee injectee ) {
142+ InjecteeImpl hk2injectee = toInjecteeImpl (injectee );
143+
144+ // Delegate the call to HK2 Resolver, Service Handle is not need in the delegated processing.
145+ return resolve (hk2injectee , null );
146+ }
147+
148+ private static InjecteeImpl toInjecteeImpl (org .glassfish .jersey .internal .inject .Injectee injectee ) {
147149 InjecteeImpl hk2injectee = new InjecteeImpl () {
148150 @ Override
149151 public Class <?> getInjecteeClass () {
@@ -152,12 +154,11 @@ public Class<?> getInjecteeClass() {
152154 };
153155 hk2injectee .setRequiredType (injectee .getRequiredType ());
154156 hk2injectee .setRequiredQualifiers (injectee .getRequiredQualifiers ());
157+ hk2injectee .setParent (injectee .getParent ());
155158 if (injectee .getInjecteeDescriptor () != null ) {
156159 hk2injectee .setInjecteeDescriptor ((ActiveDescriptor <?>) injectee .getInjecteeDescriptor ().get ());
157160 }
158-
159- // Delegate the call to HK2 Resolver, Service Handle is not need in the delegated processing.
160- return resolve (hk2injectee , null );
161+ return hk2injectee ;
161162 }
162163
163164 private Factory asFactory (final ServiceHandle handle ) {
@@ -206,9 +207,10 @@ public Class<Context> getAnnotation() {
206207 return Context .class ;
207208 }
208209
209- private final Cache <Injectee , Injectee > foreignRequestScopedInjecteeCache = new Cache <>(new Function <Injectee , Injectee >() {
210+ private final Cache <CacheKey , Injectee > foreignRequestScopedInjecteeCache = new Cache <>(new Function <CacheKey , Injectee >() {
210211 @ Override
211- public Injectee apply (Injectee injectee ) {
212+ public Injectee apply (CacheKey cacheKey ) {
213+ Injectee injectee = cacheKey .getInjectee ();
212214 if (injectee .getParent () != null ) {
213215 if (Field .class .isAssignableFrom (injectee .getParent ().getClass ())) {
214216 Field f = (Field ) injectee .getParent ();
@@ -235,7 +237,7 @@ public Injectee apply(Injectee injectee) {
235237
236238 private Set <Class <?>> getForeignRequestScopedComponents () {
237239 final List <ForeignRequestScopeBridge > scopeBridges = serviceLocator .getAllServices (ForeignRequestScopeBridge .class );
238- final Set <Class <?>> result = new HashSet <Class <?> >();
240+ final Set <Class <?>> result = new HashSet <>();
239241 for (ForeignRequestScopeBridge bridge : scopeBridges ) {
240242 final Set <Class <?>> requestScopedComponents = bridge .getRequestScopedComponents ();
241243 if (requestScopedComponents != null ) {
@@ -244,4 +246,47 @@ private Set<Class<?>> getForeignRequestScopedComponents() {
244246 }
245247 return result ;
246248 }
249+
250+ /**
251+ * Key dedicated for internal cache mechanism because two different {@link Injectee} Hk2 implementations comes from
252+ * Jersey side and HK2 side injection resolver.
253+ */
254+ private static class CacheKey {
255+
256+ private final Injectee injectee ;
257+
258+ private final int hash ;
259+
260+ private CacheKey (Injectee injectee ) {
261+ this .injectee = injectee ;
262+
263+ this .hash = Objects .hash (injectee .getInjecteeClass (),
264+ injectee .getInjecteeDescriptor (),
265+ injectee .getParent (),
266+ injectee .getRequiredQualifiers (),
267+ injectee .getRequiredType (),
268+ injectee .getPosition ());
269+ }
270+
271+ private Injectee getInjectee () {
272+ return injectee ;
273+ }
274+
275+ @ Override
276+ public boolean equals (Object o ) {
277+ if (this == o ) {
278+ return true ;
279+ }
280+ if (!(o instanceof CacheKey )) {
281+ return false ;
282+ }
283+ CacheKey cacheKey = (CacheKey ) o ;
284+ return this .hash == cacheKey .hash ;
285+ }
286+
287+ @ Override
288+ public int hashCode () {
289+ return hash ;
290+ }
291+ }
247292}
0 commit comments