Skip to content

Commit d8b74ee

Browse files
committed
OWB-1155 - InjectionPoint.getQualifiers does not return the list of selected qualifiers with type and qualifiers programmatic lookup
1 parent 43ad9a7 commit d8b74ee

2 files changed

Lines changed: 75 additions & 5 deletions

File tree

webbeans-impl/src/main/java/org/apache/webbeans/inject/instance/InstanceImpl.java

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,15 @@
1818
*/
1919
package org.apache.webbeans.inject.instance;
2020

21+
import java.io.EOFException;
2122
import java.io.IOException;
2223
import java.io.ObjectInputStream;
24+
import java.io.OptionalDataException;
2325
import java.io.ObjectOutputStream;
2426
import java.io.Serializable;
2527
import java.lang.annotation.Annotation;
2628
import java.lang.reflect.Member;
29+
import java.lang.reflect.ParameterizedType;
2730
import java.lang.reflect.Type;
2831
import java.util.Arrays;
2932
import java.util.Collections;
@@ -46,6 +49,7 @@
4649
import jakarta.inject.Provider;
4750

4851
import org.apache.webbeans.annotation.DefaultLiteral;
52+
import org.apache.webbeans.config.OwbParametrizedTypeImpl;
4953
import org.apache.webbeans.config.WebBeansContext;
5054
import org.apache.webbeans.container.BeanManagerImpl;
5155
import org.apache.webbeans.container.InjectionResolver;
@@ -237,7 +241,30 @@ public <U extends T> Instance<U> select(Class<U> subtype, Annotation... qualifie
237241
final Annotation[] effectiveQualifiers = qualifiers != null && qualifiers.length > 0
238242
? concatenateQualifiers(qualifiers)
239243
: 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);
241268
}
242269

243270
/**
@@ -404,17 +431,24 @@ private static class InstanceInjectionPoint implements InjectionPoint, Serializa
404431
{
405432
private InjectionPoint delegate;
406433
private Set<Annotation> qualifiers;
434+
private Type typeOverride;
407435

408436
protected InstanceInjectionPoint(InjectionPoint injectionPoint, Annotation[] newQualifiersArray)
437+
{
438+
this(injectionPoint, newQualifiersArray, null);
439+
}
440+
441+
protected InstanceInjectionPoint(InjectionPoint injectionPoint, Annotation[] newQualifiersArray, Type typeOverride)
409442
{
410443
this.delegate = injectionPoint;
411444
this.qualifiers = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(newQualifiersArray)));
445+
this.typeOverride = typeOverride;
412446
}
413447

414448
@Override
415449
public Type getType()
416450
{
417-
return delegate.getType();
451+
return typeOverride != null ? typeOverride : delegate.getType();
418452
}
419453

420454
@Override
@@ -458,13 +492,22 @@ private void readObject(ObjectInputStream inp) throws IOException, ClassNotFound
458492
OwbCustomObjectInputStream owbCustomObjectInputStream = new OwbCustomObjectInputStream(inp, WebBeansUtil.getCurrentClassLoader());
459493
qualifiers = Set.class.cast(owbCustomObjectInputStream.readObject());
460494
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+
}
461503
}
462504

463505
private void writeObject(ObjectOutputStream op) throws IOException
464506
{
465507
ObjectOutputStream out = new ObjectOutputStream(op);
466508
out.writeObject(qualifiers);
467509
out.writeObject(delegate);
510+
out.writeObject(typeOverride);
468511
}
469512
}
470513

webbeans-impl/src/test/java/org/apache/webbeans/test/instance/InstanceQualifierInjectionPointTest.java

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,13 @@ public class InstanceQualifierInjectionPointTest extends AbstractUnitTest
5555
@Inject
5656
private Instance<ShardContract> instance2;
5757

58+
@Inject
59+
@Any
60+
private Instance<Number> numbers;
5861

5962
@Test
6063
public void checkQualfiers() {
61-
startContainer(Arrays.<Class<?>>asList(
64+
startContainer(Arrays.asList(
6265
Qualifier1.class,
6366
QualifiersHolder.class,
6467
Factory.class), Collections.<String>emptyList(), true);
@@ -74,12 +77,27 @@ public void checkQualfiers() {
7477
assertNotNull(instance2.get());
7578
assertEquals(1, holder.getQualifiers().size());
7679
assertEquals(Default.class, holder.getQualifiers().iterator().next().annotationType());
80+
}
7781

82+
/**
83+
* OWB-1155: {@link Instance#select(Class, Annotation...)} must propagate selected qualifiers to
84+
* {@link InjectionPoint} (OWB-1122 fixed only {@link Instance#select(Annotation...)}).
85+
*/
86+
@Test
87+
public void subtypeSelectPropagatesQualifiersToInjectionPointOw1155()
88+
{
89+
startContainer(Arrays.asList(
90+
Qualifier1.class,
91+
QualifiersHolder.class,
92+
Factory.class), Collections.emptyList(), true);
7893

79-
94+
assertNotNull(numbers.select(Integer.class, new AnnotationLiteral<Qualifier1>()
95+
{
96+
}).get());
97+
assertEquals(holder.getQualifiers().toString(), 1, holder.getQualifiers().size());
98+
assertEquals(Qualifier1.class, holder.getQualifiers().iterator().next().annotationType());
8099
}
81100

82-
83101
public static class Factory
84102
{
85103
@Inject
@@ -99,6 +117,15 @@ public ShardContract produces(final InjectionPoint ip)
99117
{
100118
};
101119
}
120+
121+
@Produces
122+
@Qualifier1
123+
@Default
124+
public Integer produceNumber(final InjectionPoint ip)
125+
{
126+
holder.setQualifiers(ip.getQualifiers());
127+
return 42;
128+
}
102129
}
103130

104131
@Target(METHOD)

0 commit comments

Comments
 (0)