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

hazendaz / jmockit1 / 396

29 Oct 2025 01:10PM UTC coverage: 72.206% (-0.02%) from 72.226%
396

Pull #395

github

hazendaz
Migrate jmockit tests away from javax to jakarta
Pull Request #395: Migrate jmockit tests away from javax to jakarta

5683 of 8360 branches covered (67.98%)

Branch coverage included in aggregate %.

11946 of 16055 relevant lines covered (74.41%)

0.74 hits per line

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

73.77
/main/src/main/java/mockit/internal/injection/LifecycleMethods.java
1
/*
2
 * Copyright (c) 2006 JMockit developers
3
 * This file is subject to the terms of the MIT license (see LICENSE.txt).
4
 */
5
package mockit.internal.injection;
6

7
import static mockit.internal.injection.InjectionPoint.JAKARTA_POST_CONSTRUCT_CLASS;
8
import static mockit.internal.injection.InjectionPoint.JAKARTA_SERVLET_CLASS;
9
import static mockit.internal.injection.InjectionPoint.JAVAX_POST_CONSTRUCT_CLASS;
10
import static mockit.internal.injection.InjectionPoint.JAVAX_SERVLET_CLASS;
11
import static mockit.internal.injection.InjectionPoint.isJakartaServlet;
12
import static mockit.internal.injection.InjectionPoint.isJavaxServlet;
13
import static mockit.internal.reflection.ParameterReflection.getParameterCount;
14
import static mockit.internal.util.Utilities.NO_ARGS;
15

16
import edu.umd.cs.findbugs.annotations.NonNull;
17
import edu.umd.cs.findbugs.annotations.Nullable;
18

19
import java.lang.annotation.Annotation;
20
import java.lang.reflect.Method;
21
import java.util.ArrayList;
22
import java.util.IdentityHashMap;
23
import java.util.List;
24
import java.util.Map;
25
import java.util.Map.Entry;
26

27
import mockit.internal.reflection.MethodReflection;
28
import mockit.internal.state.TestRun;
29

30
public final class LifecycleMethods {
31

32
    @NonNull
33
    private final List<Class<?>> classesSearched;
34

35
    @NonNull
36
    private final Map<Class<?>, Method> initializationMethods;
37

38
    @NonNull
39
    private final Map<Class<?>, Method> terminationMethods;
40

41
    @NonNull
42
    private final Map<Class<?>, Object> objectsWithTerminationMethodsToExecute;
43

44
    @Nullable
45
    private Object servletConfig;
46

47
    LifecycleMethods() {
1✔
48
        classesSearched = new ArrayList<>();
1✔
49
        initializationMethods = new IdentityHashMap<>();
1✔
50
        terminationMethods = new IdentityHashMap<>();
1✔
51
        objectsWithTerminationMethodsToExecute = new IdentityHashMap<>();
1✔
52
    }
1✔
53

54
    public void findLifecycleMethods(@NonNull Class<?> testedClass) {
55
        if (testedClass.isInterface() || classesSearched.contains(testedClass)) {
1!
56
            return;
1✔
57
        }
58

59
        boolean isServlet = isJakartaServlet(testedClass);
1✔
60
        if (!isServlet) {
1!
61
            isServlet = isJavaxServlet(testedClass);
1✔
62
        }
63
        Class<?> classWithLifecycleMethods = testedClass;
1✔
64

65
        do {
66
            findLifecycleMethodsInSingleClass(isServlet, classWithLifecycleMethods);
1✔
67
            classWithLifecycleMethods = classWithLifecycleMethods.getSuperclass();
1✔
68
        } while (classWithLifecycleMethods != Object.class);
1✔
69

70
        classesSearched.add(testedClass);
1✔
71
    }
1✔
72

73
    private void findLifecycleMethodsInSingleClass(boolean isServlet, @NonNull Class<?> classWithLifecycleMethods) {
74
        Method initializationMethod = null;
1✔
75
        Method terminationMethod = null;
1✔
76
        int methodsFoundInSameClass = 0;
1✔
77

78
        for (Method method : classWithLifecycleMethods.getDeclaredMethods()) {
1✔
79
            if (method.isSynthetic()) {
1✔
80
                continue;
1✔
81
            }
82

83
            if (initializationMethod == null && isInitializationMethod(method, isServlet)) {
1✔
84
                initializationMethods.put(classWithLifecycleMethods, method);
1✔
85
                initializationMethod = method;
1✔
86
                methodsFoundInSameClass++;
1✔
87
            } else if (terminationMethod == null && isTerminationMethod(method, isServlet)) {
1!
88
                terminationMethods.put(classWithLifecycleMethods, method);
1✔
89
                terminationMethod = method;
1✔
90
                methodsFoundInSameClass++;
1✔
91
            }
92

93
            if (methodsFoundInSameClass == 2) {
1✔
94
                break;
1✔
95
            }
96
        }
97
    }
1✔
98

99
    private static boolean isInitializationMethod(@NonNull Method method, boolean isServlet) {
100
        if (hasLifecycleAnnotationJakarta(method, true) || hasLifecycleAnnotationJavax(method, true)) {
1!
101
            return true;
1✔
102
        }
103

104
        if (isServlet && "init".equals(method.getName())) {
1!
105
            Class<?>[] parameterTypes = method.getParameterTypes();
×
106

107
            if (parameterTypes.length != 1) {
×
108
                return false;
×
109
            }
110
            return (JAKARTA_SERVLET_CLASS != null && parameterTypes[0] == jakarta.servlet.ServletConfig.class)
×
111
                    || (JAVAX_SERVLET_CLASS != null && parameterTypes[0] == javax.servlet.ServletConfig.class);
112
        }
113

114
        return false;
1✔
115
    }
116

117
    private static boolean hasLifecycleAnnotationJakarta(@NonNull Method method, boolean postConstruct) {
118
        if (JAKARTA_POST_CONSTRUCT_CLASS == null) {
1!
119
            return false;
×
120
        }
121

122
        try {
123
            Class<? extends Annotation> lifecycleAnnotation = postConstruct ? jakarta.annotation.PostConstruct.class
1✔
124
                    : jakarta.annotation.PreDestroy.class;
1✔
125

126
            if (method.isAnnotationPresent(lifecycleAnnotation)) {
1✔
127
                return true;
1✔
128
            }
129
        } catch (NoClassDefFoundError ignore) {
×
130
            /* can occur on JDK 9 */ }
1✔
131

132
        return false;
1✔
133
    }
134

135
    private static boolean hasLifecycleAnnotationJavax(@NonNull Method method, boolean postConstruct) {
136
        if (JAVAX_POST_CONSTRUCT_CLASS == null) {
1!
137
            return false;
×
138
        }
139

140
        try {
141
            Class<? extends Annotation> lifecycleAnnotation = postConstruct ? javax.annotation.PostConstruct.class
1✔
142
                    : javax.annotation.PreDestroy.class;
1✔
143

144
            if (method.isAnnotationPresent(lifecycleAnnotation)) {
1!
145
                return true;
×
146
            }
147
        } catch (NoClassDefFoundError ignore) {
×
148
            /* can occur on JDK 9 */ }
1✔
149

150
        return false;
1✔
151
    }
152

153
    private static boolean isTerminationMethod(@NonNull Method method, boolean isServlet) {
154
        return hasLifecycleAnnotationJakarta(method, false) || hasLifecycleAnnotationJavax(method, false)
1!
155
                || isServlet && "destroy".equals(method.getName()) && getParameterCount(method) == 0;
1!
156
    }
157

158
    public void executeInitializationMethodsIfAny(@NonNull Class<?> testedClass, @NonNull Object testedObject) {
159
        Class<?> superclass = testedClass.getSuperclass();
1✔
160

161
        if (superclass != Object.class) {
1✔
162
            executeInitializationMethodsIfAny(superclass, testedObject);
1✔
163
        }
164

165
        Method postConstructMethod = initializationMethods.get(testedClass);
1✔
166

167
        if (postConstructMethod != null) {
1✔
168
            executeInitializationMethod(testedObject, postConstructMethod);
1✔
169
        }
170

171
        Method preDestroyMethod = terminationMethods.get(testedClass);
1✔
172

173
        if (preDestroyMethod != null) {
1✔
174
            objectsWithTerminationMethodsToExecute.put(testedClass, testedObject);
1✔
175
        }
176
    }
1✔
177

178
    private void executeInitializationMethod(@NonNull Object testedObject, @NonNull Method initializationMethod) {
179
        Object[] args = NO_ARGS;
1✔
180

181
        if ("init".equals(initializationMethod.getName()) && getParameterCount(initializationMethod) == 1) {
1!
182
            args = new Object[] { servletConfig };
×
183
        }
184

185
        TestRun.exitNoMockingZone();
1✔
186

187
        try {
188
            MethodReflection.invoke(testedObject, initializationMethod, args);
1✔
189
        } finally {
190
            TestRun.enterNoMockingZone();
1✔
191
        }
192
    }
1✔
193

194
    void executeTerminationMethodsIfAny() {
195
        try {
196
            for (Entry<Class<?>, Object> testedClassAndObject : objectsWithTerminationMethodsToExecute.entrySet()) {
1✔
197
                executeTerminationMethod(testedClassAndObject.getKey(), testedClassAndObject.getValue());
1✔
198
            }
1✔
199
        } finally {
200
            objectsWithTerminationMethodsToExecute.clear();
1✔
201
        }
202
    }
1✔
203

204
    private void executeTerminationMethod(@NonNull Class<?> testedClass, @NonNull Object testedObject) {
205
        Method terminationMethod = terminationMethods.get(testedClass);
1✔
206
        TestRun.exitNoMockingZone();
1✔
207

208
        try {
209
            MethodReflection.invoke(testedObject, terminationMethod);
1✔
210
        } catch (RuntimeException | AssertionError ignore) {
×
211
        } finally {
212
            TestRun.enterNoMockingZone();
1✔
213
        }
214
    }
1✔
215

216
    void getServletConfigForInitMethodsIfAny(@NonNull List<? extends InjectionProvider> injectables,
217
            @NonNull Object testClassInstance) {
218
        for (InjectionProvider injectable : injectables) {
1✔
219
            // Try Jakarta first
220
            if (JAKARTA_SERVLET_CLASS != null && injectable.getDeclaredType() == jakarta.servlet.ServletConfig.class) {
1!
221
                servletConfig = injectable.getValue(testClassInstance);
×
222
                break;
×
223
            }
224

225
            // Then try Javax
226
            if (JAVAX_SERVLET_CLASS != null && injectable.getDeclaredType() == javax.servlet.ServletConfig.class) {
1!
227
                servletConfig = injectable.getValue(testClassInstance);
×
228
                break;
×
229
            }
230
        }
1✔
231
    }
1✔
232

233
}
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