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
2525import java .security .PrivilegedAction ;
2626import java .util .List ;
2727import java .util .Set ;
28- import java .util .function .Supplier ;
2928
3029import javax .inject .Inject ;
3130import javax .inject .Named ;
3534import org .glassfish .jersey .internal .LocalizationMessages ;
3635import org .glassfish .jersey .internal .inject .InjectionResolver ;
3736import 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
4238import org .glassfish .hk2 .api .ClassAnalyzer ;
4339import 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