• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

hazendaz / jmockit1 / 496

15 Nov 2025 05:33PM UTC coverage: 72.192% (-0.008%) from 72.2%
496

push

github

web-flow
Merge pull request #412 from hazendaz/renovate/major-spring-core

Update spring core to v7 (major)

5677 of 8360 branches covered (67.91%)

Branch coverage included in aggregate %.

11922 of 16018 relevant lines covered (74.43%)

0.74 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

75.41
/main/src/main/java/mockit/internal/injection/full/FullInjection.java
1
/*
2
 * MIT License
3
 * Copyright (c) 2006-2025 JMockit developers
4
 * See LICENSE file for full license text.
5
 */
6
package mockit.internal.injection.full;
7

8
import static java.lang.reflect.Modifier.isStatic;
9

10
import static mockit.internal.injection.InjectionPoint.JAKARTA_CONVERSATION_CLASS;
11
import static mockit.internal.injection.InjectionPoint.JAKARTA_INJECT_CLASS;
12
import static mockit.internal.injection.InjectionPoint.JAKARTA_PERSISTENCE_UNIT_CLASS;
13
import static mockit.internal.injection.InjectionPoint.JAKARTA_RESOURCE_CLASS;
14
import static mockit.internal.injection.InjectionPoint.JAKARTA_SERVLET_CLASS;
15
import static mockit.internal.injection.InjectionPoint.JAVAX_CONVERSATION_CLASS;
16
import static mockit.internal.injection.InjectionPoint.JAVAX_INJECT_CLASS;
17
import static mockit.internal.injection.InjectionPoint.JAVAX_PERSISTENCE_UNIT_CLASS;
18
import static mockit.internal.injection.InjectionPoint.JAVAX_RESOURCE_CLASS;
19
import static mockit.internal.injection.InjectionPoint.JAVAX_SERVLET_CLASS;
20
import static mockit.internal.reflection.ConstructorReflection.newInstanceUsingDefaultConstructorIfAvailable;
21
import static mockit.internal.util.Utilities.getClassType;
22

23
import edu.umd.cs.findbugs.annotations.NonNull;
24
import edu.umd.cs.findbugs.annotations.Nullable;
25

26
import java.lang.annotation.Annotation;
27
import java.lang.reflect.ParameterizedType;
28
import java.lang.reflect.Type;
29
import java.lang.reflect.TypeVariable;
30
import java.util.logging.Logger;
31

32
import javax.sql.CommonDataSource;
33

34
import mockit.asm.jvmConstants.Access;
35
import mockit.internal.injection.InjectionPoint;
36
import mockit.internal.injection.InjectionProvider;
37
import mockit.internal.injection.InjectionState;
38
import mockit.internal.injection.Injector;
39
import mockit.internal.injection.TestedClass;
40
import mockit.internal.injection.TestedObjectCreation;
41

42
/**
43
 * Responsible for recursive injection of dependencies into a <code>@Tested(fullyInitialized = true)</code> object.
44
 */
45
public final class FullInjection {
1✔
46
    private static final int INVALID_TYPES = Access.ABSTRACT + Access.ANNOTATION + Access.ENUM;
47

48
    @NonNull
49
    private final InjectionState injectionState;
50

51
    @NonNull
52
    private final String testedClassName;
53

54
    @NonNull
55
    private final String testedName;
56

57
    @Nullable
58
    private final ServletJakartaDependencies servletJakartaDependencies;
59
    @Nullable
60
    private final ServletJavaxDependencies servletJavaxDependencies;
61

62
    @Nullable
63
    private final JPAJakartaDependencies jpaJakartaDependencies;
64
    @Nullable
65
    private final JPAJavaxDependencies jpaJavaxDependencies;
66

67
    @Nullable
68
    private Class<?> dependencyClass;
69

70
    @Nullable
71
    private InjectionProvider parentInjectionProvider;
72

73
    public FullInjection(@NonNull InjectionState injectionState, @NonNull Class<?> testedClass,
74
            @NonNull String testedName) {
1✔
75
        this.injectionState = injectionState;
1✔
76
        testedClassName = testedClass.getSimpleName();
1✔
77
        this.testedName = testedName;
1✔
78
        servletJakartaDependencies = JAKARTA_SERVLET_CLASS == null ? null
1!
79
                : new ServletJakartaDependencies(injectionState);
1✔
80
        servletJavaxDependencies = JAVAX_SERVLET_CLASS == null ? null : new ServletJavaxDependencies(injectionState);
1!
81
        jpaJakartaDependencies = JAKARTA_PERSISTENCE_UNIT_CLASS == null ? null
1!
82
                : new JPAJakartaDependencies(injectionState);
1✔
83
        jpaJavaxDependencies = JAVAX_PERSISTENCE_UNIT_CLASS == null ? null : new JPAJavaxDependencies(injectionState);
1!
84
    }
1✔
85

86
    @Nullable
87
    public Object createOrReuseInstance(@NonNull TestedClass testedClass, @NonNull Injector injector,
88
            @Nullable InjectionProvider injectionProvider, @Nullable String qualifiedName) {
89
        setInjectionProvider(injectionProvider);
1✔
90

91
        InjectionPoint injectionPoint = getInjectionPoint(testedClass, injectionProvider, qualifiedName);
1✔
92
        Object dependency = injectionState.getInstantiatedDependency(testedClass, injectionPoint);
1✔
93

94
        if (dependency != null) {
1✔
95
            return dependency;
1✔
96
        }
97

98
        Class<?> typeToInject = dependencyClass;
1✔
99

100
        if (typeToInject == Logger.class) {
1✔
101
            return createLogger(testedClass);
1✔
102
        }
103

104
        if (typeToInject == null || !isInstantiableType(typeToInject)) {
1!
105
            return null;
1✔
106
        }
107

108
        return createInstance(testedClass, injector, injectionProvider, injectionPoint);
1✔
109
    }
110

111
    public void setInjectionProvider(@Nullable InjectionProvider injectionProvider) {
112
        if (injectionProvider != null) {
1✔
113
            injectionProvider.parent = parentInjectionProvider;
1✔
114
        }
115

116
        parentInjectionProvider = injectionProvider;
1✔
117
    }
1✔
118

119
    @NonNull
120
    private InjectionPoint getInjectionPoint(@NonNull TestedClass testedClass,
121
            @Nullable InjectionProvider injectionProvider, @Nullable String qualifiedName) {
122
        if (injectionProvider == null) {
1✔
123
            dependencyClass = testedClass.targetClass;
1✔
124
            return new InjectionPoint(dependencyClass, qualifiedName, true);
1✔
125
        }
126

127
        Type dependencyType = injectionProvider.getDeclaredType();
1✔
128

129
        if (dependencyType instanceof TypeVariable<?>) {
1✔
130
            dependencyType = testedClass.reflection.resolveTypeVariable((TypeVariable<?>) dependencyType);
1✔
131
            dependencyClass = getClassType(dependencyType);
1✔
132
        } else {
133
            dependencyClass = injectionProvider.getClassOfDeclaredType();
1✔
134
        }
135

136
        if (qualifiedName != null && !qualifiedName.isEmpty()) {
1!
137
            return new InjectionPoint(dependencyClass, qualifiedName, true);
1✔
138
        }
139

140
        if (jpaJakartaDependencies != null && JPAJakartaDependencies.isApplicable(dependencyClass)) {
1!
141
            for (Annotation annotation : injectionProvider.getAnnotations()) {
1✔
142
                InjectionPoint injectionPoint = jpaJakartaDependencies.getInjectionPointIfAvailable(annotation);
1✔
143

144
                if (injectionPoint != null) {
1!
145
                    return injectionPoint;
1✔
146
                }
147
            }
148
        }
149

150
        if (jpaJavaxDependencies != null && JPAJavaxDependencies.isApplicable(dependencyClass)) {
1!
151
            for (Annotation annotation : injectionProvider.getAnnotations()) {
×
152
                InjectionPoint injectionPoint = jpaJavaxDependencies.getInjectionPointIfAvailable(annotation);
×
153

154
                if (injectionPoint != null) {
×
155
                    return injectionPoint;
×
156
                }
157
            }
158
        }
159

160
        return new InjectionPoint(dependencyType, injectionProvider.getName(), false);
1✔
161
    }
162

163
    @NonNull
164
    private static Object createLogger(@NonNull TestedClass testedClass) {
165
        TestedClass testedClassWithLogger = testedClass.parent;
1✔
166
        assert testedClassWithLogger != null;
1!
167
        return Logger.getLogger(testedClassWithLogger.nameOfTestedClass);
1✔
168
    }
169

170
    public static boolean isInstantiableType(@NonNull Class<?> type) {
171
        if (type.isPrimitive() || type.isArray() || type.isAnnotation()) {
1!
172
            return false;
1✔
173
        }
174

175
        if (type.isInterface()) {
1✔
176
            return true;
1✔
177
        }
178

179
        int typeModifiers = type.getModifiers();
1✔
180

181
        if ((typeModifiers & INVALID_TYPES) != 0 || !isStatic(typeModifiers) && type.isMemberClass()) {
1!
182
            return false;
1✔
183
        }
184

185
        return type.getClassLoader() != null;
1✔
186
    }
187

188
    @Nullable
189
    private Object createInstance(@NonNull TestedClass testedClass, @NonNull Injector injector,
190
            @Nullable InjectionProvider injectionProvider, @NonNull InjectionPoint injectionPoint) {
191
        @SuppressWarnings("ConstantConditions")
192
        @NonNull
193
        Class<?> typeToInject = dependencyClass;
1✔
194
        Object dependency = null;
1✔
195

196
        if (typeToInject.isInterface()) {
1✔
197
            dependency = createInstanceOfSupportedInterfaceIfApplicable(testedClass, typeToInject, injectionPoint,
1✔
198
                    injectionProvider);
199

200
            if (dependency == null && typeToInject.getClassLoader() != null) {
1✔
201
                Class<?> resolvedType = injectionState.resolveInterface(typeToInject);
1✔
202

203
                if (resolvedType != null && !resolvedType.isInterface()) {
1!
204
                    // noinspection AssignmentToMethodParameter
205
                    testedClass = new TestedClass(resolvedType, resolvedType);
1✔
206
                    typeToInject = resolvedType;
1✔
207
                }
208
            }
209
        }
210

211
        if (dependency == null) {
1✔
212
            dependency = createAndRegisterNewInstance(typeToInject, testedClass, injector, injectionPoint,
1✔
213
                    injectionProvider);
214
        }
215

216
        return dependency;
1✔
217
    }
218

219
    @Nullable
220
    private Object createInstanceOfSupportedInterfaceIfApplicable(@NonNull TestedClass testedClass,
221
            @NonNull Class<?> typeToInject, @NonNull InjectionPoint injectionPoint,
222
            @Nullable InjectionProvider injectionProvider) {
223
        Object dependency = null;
1✔
224

225
        if (CommonDataSource.class.isAssignableFrom(typeToInject)) {
1✔
226
            dependency = createAndRegisterDataSource(testedClass, injectionPoint, injectionProvider);
1✔
227
        } else if (JAKARTA_INJECT_CLASS != null && typeToInject == jakarta.inject.Provider.class) {
1!
228
            assert injectionProvider != null;
1!
229
            dependency = createProviderJakartaInstance(injectionProvider);
1✔
230
        } else if (JAVAX_INJECT_CLASS != null && typeToInject == javax.inject.Provider.class) {
1!
231
            assert injectionProvider != null;
×
232
            dependency = createProviderJavaxInstance(injectionProvider);
×
233
        } else if (JAKARTA_CONVERSATION_CLASS != null
1!
234
                && typeToInject == jakarta.enterprise.context.Conversation.class) {
235
            dependency = createAndRegisterConversationJakartaInstance();
1✔
236
        } else if (JAVAX_CONVERSATION_CLASS != null && typeToInject == javax.enterprise.context.Conversation.class) {
1!
237
            dependency = createAndRegisterConversationJavaxInstance();
×
238
        } else if (servletJakartaDependencies != null && ServletJakartaDependencies.isApplicable(typeToInject)) {
1!
239
            dependency = servletJakartaDependencies.createAndRegisterDependency(typeToInject);
1✔
240
        } else if (servletJavaxDependencies != null && ServletJavaxDependencies.isApplicable(typeToInject)) {
1!
241
            dependency = servletJavaxDependencies.createAndRegisterDependency(typeToInject);
×
242
        } else if (jpaJakartaDependencies != null && JPAJakartaDependencies.isApplicable(typeToInject)) {
1!
243
            dependency = jpaJakartaDependencies.createAndRegisterDependency(typeToInject, injectionPoint,
1✔
244
                    injectionProvider);
245
        } else if (jpaJavaxDependencies != null && JPAJavaxDependencies.isApplicable(typeToInject)) {
1!
246
            dependency = jpaJavaxDependencies.createAndRegisterDependency(typeToInject, injectionPoint,
×
247
                    injectionProvider);
248
        }
249

250
        return dependency;
1✔
251
    }
252

253
    @Nullable
254
    private Object createAndRegisterDataSource(@NonNull TestedClass testedClass, @NonNull InjectionPoint injectionPoint,
255
            @Nullable InjectionProvider injectionProvider) {
256
        if (injectionProvider == null) {
1!
257
            return null;
×
258
        }
259

260
        // Check annotation is present (both jars)
261
        if ((JAKARTA_RESOURCE_CLASS != null && injectionProvider.hasAnnotation(jakarta.annotation.Resource.class))
1!
262
                || (JAVAX_RESOURCE_CLASS != null && injectionProvider.hasAnnotation(javax.annotation.Resource.class))) {
1!
263
            TestDataSource dsCreation = new TestDataSource(injectionPoint);
1✔
264
            CommonDataSource dataSource = dsCreation.createIfDataSourceDefinitionAvailable(testedClass);
1✔
265

266
            if (dataSource != null) {
1!
267
                injectionState.saveInstantiatedDependency(injectionPoint, dataSource);
1✔
268
            }
269

270
            return dataSource;
1✔
271
        }
272

273
        return null;
1✔
274
    }
275

276
    @NonNull
277
    private Object createProviderJakartaInstance(@NonNull InjectionProvider injectionProvider) {
278
        ParameterizedType genericType = (ParameterizedType) injectionProvider.getDeclaredType();
1✔
279
        final Class<?> providedClass = (Class<?>) genericType.getActualTypeArguments()[0];
1✔
280

281
        if (providedClass.isAnnotationPresent(jakarta.inject.Singleton.class)) {
1✔
282
            return new jakarta.inject.Provider<Object>() {
1✔
283
                private Object dependency;
284

285
                @Override
286
                public synchronized Object get() {
287
                    if (dependency == null) {
1✔
288
                        dependency = createNewInstance(providedClass, true);
1✔
289
                    }
290

291
                    return dependency;
1✔
292
                }
293
            };
294
        }
295

296
        return (jakarta.inject.Provider<Object>) () -> createNewInstance(providedClass, false);
1✔
297
    }
298

299
    @NonNull
300
    private Object createProviderJavaxInstance(@NonNull InjectionProvider injectionProvider) {
301
        ParameterizedType genericType = (ParameterizedType) injectionProvider.getDeclaredType();
×
302
        final Class<?> providedClass = (Class<?>) genericType.getActualTypeArguments()[0];
×
303

304
        if (providedClass.isAnnotationPresent(javax.inject.Singleton.class)) {
×
305
            return new javax.inject.Provider<Object>() {
×
306
                private Object dependency;
307

308
                @Override
309
                public synchronized Object get() {
310
                    if (dependency == null) {
×
311
                        dependency = createNewInstance(providedClass, true);
×
312
                    }
313

314
                    return dependency;
×
315
                }
316
            };
317
        }
318

319
        return (javax.inject.Provider<Object>) () -> createNewInstance(providedClass, false);
×
320
    }
321

322
    @Nullable
323
    private Object createNewInstance(@NonNull Class<?> classToInstantiate, boolean required) {
324
        if (classToInstantiate.isInterface()) {
1✔
325
            return null;
1✔
326
        }
327

328
        if (classToInstantiate.getClassLoader() == null) {
1!
329
            return newInstanceUsingDefaultConstructorIfAvailable(classToInstantiate);
×
330
        }
331

332
        return new TestedObjectCreation(injectionState, this, classToInstantiate).create(required, false);
1✔
333
    }
334

335
    @NonNull
336
    private Object createAndRegisterConversationJakartaInstance() {
337
        jakarta.enterprise.context.Conversation conversation = new TestConversationJakarta();
1✔
338

339
        InjectionPoint injectionPoint = new InjectionPoint(jakarta.enterprise.context.Conversation.class);
1✔
340
        injectionState.saveInstantiatedDependency(injectionPoint, conversation);
1✔
341
        return conversation;
1✔
342
    }
343

344
    @NonNull
345
    private Object createAndRegisterConversationJavaxInstance() {
346
        javax.enterprise.context.Conversation conversation = new TestConversationJavax();
×
347

348
        InjectionPoint injectionPoint = new InjectionPoint(javax.enterprise.context.Conversation.class);
×
349
        injectionState.saveInstantiatedDependency(injectionPoint, conversation);
×
350
        return conversation;
×
351
    }
352

353
    @Nullable
354
    private Object createAndRegisterNewInstance(@NonNull Class<?> typeToInstantiate, @NonNull TestedClass testedClass,
355
            @NonNull Injector injector, @NonNull InjectionPoint injectionPoint,
356
            @Nullable InjectionProvider injectionProvider) {
357
        Object dependency = createNewInstance(typeToInstantiate,
1✔
358
                injectionProvider != null && injectionProvider.isRequired());
1✔
359

360
        if (dependency != null) {
1✔
361
            if (injectionPoint.name == null) {
1!
362
                assert injectionProvider != null;
×
363
                injectionPoint = new InjectionPoint(injectionPoint.type, injectionProvider.getName());
×
364
            }
365

366
            registerNewInstance(testedClass, injector, injectionPoint, dependency);
1✔
367
        }
368

369
        return dependency;
1✔
370
    }
371

372
    private void registerNewInstance(@NonNull TestedClass testedClass, @NonNull Injector injector,
373
            @NonNull InjectionPoint injectionPoint, @NonNull Object dependency) {
374
        injectionState.saveInstantiatedDependency(injectionPoint, dependency);
1✔
375

376
        Class<?> instantiatedClass = dependency.getClass();
1✔
377

378
        if (testedClass.isClassFromSameModuleOrSystemAsTestedClass(instantiatedClass)) {
1!
379
            injector.fillOutDependenciesRecursively(dependency, testedClass);
1✔
380
            injectionState.lifecycleMethods.findLifecycleMethods(instantiatedClass);
1✔
381
            injectionState.lifecycleMethods.executeInitializationMethodsIfAny(instantiatedClass, dependency);
1✔
382
        }
383
    }
1✔
384

385
    @Override
386
    public String toString() {
387
        String description = "@Tested object \"" + testedClassName + ' ' + testedName + '"';
1✔
388

389
        if (parentInjectionProvider != null) {
1!
390
            InjectionProvider injectionProvider = parentInjectionProvider.parent;
1✔
391

392
            if (injectionProvider != null) {
1!
393
                description = injectionProvider + "\r\n  of " + description;
1✔
394
            }
395
        }
396

397
        return description;
1✔
398
    }
399

400
    public void clear() {
401
        parentInjectionProvider = null;
1✔
402
    }
1✔
403
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc