|
18 | 18 | */ |
19 | 19 | package org.apache.webbeans.inject.instance; |
20 | 20 |
|
| 21 | +import java.io.EOFException; |
21 | 22 | import java.io.IOException; |
22 | 23 | import java.io.ObjectInputStream; |
| 24 | +import java.io.OptionalDataException; |
23 | 25 | import java.io.ObjectOutputStream; |
24 | 26 | import java.io.Serializable; |
25 | 27 | import java.lang.annotation.Annotation; |
26 | 28 | import java.lang.reflect.Member; |
| 29 | +import java.lang.reflect.ParameterizedType; |
27 | 30 | import java.lang.reflect.Type; |
28 | 31 | import java.util.Arrays; |
29 | 32 | import java.util.Collections; |
|
46 | 49 | import jakarta.inject.Provider; |
47 | 50 |
|
48 | 51 | import org.apache.webbeans.annotation.DefaultLiteral; |
| 52 | +import org.apache.webbeans.config.OwbParametrizedTypeImpl; |
49 | 53 | import org.apache.webbeans.config.WebBeansContext; |
50 | 54 | import org.apache.webbeans.container.BeanManagerImpl; |
51 | 55 | import org.apache.webbeans.container.InjectionResolver; |
@@ -237,7 +241,30 @@ public <U extends T> Instance<U> select(Class<U> subtype, Annotation... qualifie |
237 | 241 | final Annotation[] effectiveQualifiers = qualifiers != null && qualifiers.length > 0 |
238 | 242 | ? concatenateQualifiers(qualifiers) |
239 | 243 | : qualifierAnnotations.toArray(new Annotation[0]); |
240 | | - return new InstanceImpl<>(sub, injectionPoint, webBeansContext, effectiveQualifiers); |
| 244 | + final InjectionPoint nextInjectionPoint = injectionPoint == null ? null |
| 245 | + : new InstanceInjectionPoint(injectionPoint, effectiveQualifiers, instanceTypeOverrideForSelectClass(injectionPoint, sub)); |
| 246 | + return new InstanceImpl<>(sub, nextInjectionPoint, webBeansContext, effectiveQualifiers); |
| 247 | + } |
| 248 | + |
| 249 | + /** |
| 250 | + * OWB-1155: only override {@link InjectionPoint#getType()} to {@code Instance<subtype>} when the |
| 251 | + * current injection point already represents an {@code Instance<…>} dependency. Otherwise |
| 252 | + * (e.g. {@code BeanConfiguratorImpl#createInstance} uses {@code Object} with the field's |
| 253 | + * {@link InjectionPoint}) forcing {@code Instance<subtype>} breaks {@link org.apache.webbeans.portable.InjectionPointProducer}. |
| 254 | + */ |
| 255 | + private static Type instanceTypeOverrideForSelectClass(InjectionPoint injectionPoint, Type sub) |
| 256 | + { |
| 257 | + Type t = injectionPoint.getType(); |
| 258 | + if (!ParameterizedType.class.isInstance(t)) |
| 259 | + { |
| 260 | + return null; |
| 261 | + } |
| 262 | + ParameterizedType pt = ParameterizedType.class.cast(t); |
| 263 | + if (pt.getRawType() != Instance.class) |
| 264 | + { |
| 265 | + return null; |
| 266 | + } |
| 267 | + return new OwbParametrizedTypeImpl(null, Instance.class, sub); |
241 | 268 | } |
242 | 269 |
|
243 | 270 | /** |
@@ -404,17 +431,24 @@ private static class InstanceInjectionPoint implements InjectionPoint, Serializa |
404 | 431 | { |
405 | 432 | private InjectionPoint delegate; |
406 | 433 | private Set<Annotation> qualifiers; |
| 434 | + private Type typeOverride; |
407 | 435 |
|
408 | 436 | protected InstanceInjectionPoint(InjectionPoint injectionPoint, Annotation[] newQualifiersArray) |
| 437 | + { |
| 438 | + this(injectionPoint, newQualifiersArray, null); |
| 439 | + } |
| 440 | + |
| 441 | + protected InstanceInjectionPoint(InjectionPoint injectionPoint, Annotation[] newQualifiersArray, Type typeOverride) |
409 | 442 | { |
410 | 443 | this.delegate = injectionPoint; |
411 | 444 | this.qualifiers = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(newQualifiersArray))); |
| 445 | + this.typeOverride = typeOverride; |
412 | 446 | } |
413 | 447 |
|
414 | 448 | @Override |
415 | 449 | public Type getType() |
416 | 450 | { |
417 | | - return delegate.getType(); |
| 451 | + return typeOverride != null ? typeOverride : delegate.getType(); |
418 | 452 | } |
419 | 453 |
|
420 | 454 | @Override |
@@ -458,13 +492,22 @@ private void readObject(ObjectInputStream inp) throws IOException, ClassNotFound |
458 | 492 | OwbCustomObjectInputStream owbCustomObjectInputStream = new OwbCustomObjectInputStream(inp, WebBeansUtil.getCurrentClassLoader()); |
459 | 493 | qualifiers = Set.class.cast(owbCustomObjectInputStream.readObject()); |
460 | 494 | delegate = InjectionPoint.class.cast(owbCustomObjectInputStream.readObject()); |
| 495 | + try |
| 496 | + { |
| 497 | + typeOverride = Type.class.cast(owbCustomObjectInputStream.readObject()); |
| 498 | + } |
| 499 | + catch (EOFException | OptionalDataException ex) |
| 500 | + { |
| 501 | + typeOverride = null; |
| 502 | + } |
461 | 503 | } |
462 | 504 |
|
463 | 505 | private void writeObject(ObjectOutputStream op) throws IOException |
464 | 506 | { |
465 | 507 | ObjectOutputStream out = new ObjectOutputStream(op); |
466 | 508 | out.writeObject(qualifiers); |
467 | 509 | out.writeObject(delegate); |
| 510 | + out.writeObject(typeOverride); |
468 | 511 | } |
469 | 512 | } |
470 | 513 |
|
|
0 commit comments