Skip to content

Commit de109ab

Browse files
jbescossenivam
authored andcommitted
Deadlock with JerseyClassAnalyzer#resolverAnnotations #5996
Signed-off-by: Jorge Bescos Gascon <[email protected]>
1 parent 7ea3893 commit de109ab

File tree

1 file changed

+14
-20
lines changed

1 file changed

+14
-20
lines changed

inject/hk2/src/main/java/org/glassfish/jersey/inject/hk2/JerseyClassAnalyzer.java

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2019 Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2017, 2025 Oracle and/or its affiliates. All rights reserved.
33
*
44
* This program and the accompanying materials are made available under the
55
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -25,7 +25,6 @@
2525
import java.security.PrivilegedAction;
2626
import java.util.List;
2727
import java.util.Set;
28-
import java.util.function.Supplier;
2928

3029
import javax.inject.Inject;
3130
import javax.inject.Named;
@@ -35,9 +34,6 @@
3534
import org.glassfish.jersey.internal.LocalizationMessages;
3635
import org.glassfish.jersey.internal.inject.InjectionResolver;
3736
import org.glassfish.jersey.internal.util.collection.ImmutableCollectors;
38-
import org.glassfish.jersey.internal.util.collection.LazyValue;
39-
import org.glassfish.jersey.internal.util.collection.Value;
40-
import org.glassfish.jersey.internal.util.collection.Values;
4137

4238
import org.glassfish.hk2.api.ClassAnalyzer;
4339
import org.glassfish.hk2.api.MultiException;
@@ -79,33 +75,31 @@ public Binder(ServiceLocator serviceLocator) {
7975

8076
@Override
8177
protected void configure() {
82-
ClassAnalyzer defaultAnalyzer =
83-
serviceLocator.getService(ClassAnalyzer.class, ClassAnalyzer.DEFAULT_IMPLEMENTATION_NAME);
84-
85-
Supplier<List<InjectionResolver>> resolvers = () -> serviceLocator.getAllServices(InjectionResolver.class);
86-
87-
bind(new JerseyClassAnalyzer(defaultAnalyzer, resolvers))
78+
bind(JerseyClassAnalyzer.class)
8879
.analyzeWith(ClassAnalyzer.DEFAULT_IMPLEMENTATION_NAME)
8980
.named(JerseyClassAnalyzer.NAME)
9081
.to(ClassAnalyzer.class);
9182
}
9283
}
9384

85+
private final Set<Class> resolverAnnotations;
9486
private final ClassAnalyzer defaultAnalyzer;
95-
private final LazyValue<Set<Class>> resolverAnnotations;
87+
9688
/**
9789
* Injection constructor.
9890
*
99-
* @param defaultAnalyzer default HK2 class analyzer.
100-
* @param supplierResolvers configured injection resolvers.
91+
* @param serviceLocator current injection manager.
10192
*/
102-
private JerseyClassAnalyzer(ClassAnalyzer defaultAnalyzer, Supplier<List<InjectionResolver>> supplierResolvers) {
103-
this.defaultAnalyzer = defaultAnalyzer;
104-
Value<Set<Class>> resolvers = () -> supplierResolvers.get().stream()
93+
@Inject
94+
public JerseyClassAnalyzer(ServiceLocator serviceLocator) {
95+
defaultAnalyzer = serviceLocator.getService(ClassAnalyzer.class, ClassAnalyzer.DEFAULT_IMPLEMENTATION_NAME);
96+
// Load the resolver annotations once to avoid potential deadlock later
97+
// See https://github.com/eclipse-ee4j/jersey/issues/5996
98+
List<InjectionResolver> resolvers = serviceLocator.getAllServices(InjectionResolver.class);
99+
this.resolverAnnotations = resolvers.stream()
105100
.filter(InjectionResolver::isConstructorParameterIndicator)
106101
.map(InjectionResolver::getAnnotation)
107102
.collect(ImmutableCollectors.toImmutableSet());
108-
this.resolverAnnotations = Values.lazy(resolvers);
109103
}
110104

111105
@SuppressWarnings("unchecked")
@@ -186,7 +180,7 @@ private boolean isCompatible(final Constructor<?> constructor) {
186180

187181
final int paramSize = constructor.getParameterTypes().length;
188182

189-
if (paramSize != 0 && resolverAnnotations.get().isEmpty()) {
183+
if (paramSize != 0 && resolverAnnotations.isEmpty()) {
190184
return false;
191185
}
192186

@@ -200,7 +194,7 @@ private boolean isCompatible(final Constructor<?> constructor) {
200194
for (final Annotation[] paramAnnotations : constructor.getParameterAnnotations()) {
201195
boolean found = false;
202196
for (final Annotation paramAnnotation : paramAnnotations) {
203-
if (resolverAnnotations.get().contains(paramAnnotation.annotationType())) {
197+
if (resolverAnnotations.contains(paramAnnotation.annotationType())) {
204198
found = true;
205199
break;
206200
}

0 commit comments

Comments
 (0)