• 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

67.02
/main/src/main/java/mockit/internal/reflection/MethodReflection.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.reflection;
7

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

11
import static mockit.internal.reflection.ParameterReflection.*;
12

13
import edu.umd.cs.findbugs.annotations.NonNull;
14
import edu.umd.cs.findbugs.annotations.Nullable;
15

16
import java.lang.reflect.InvocationTargetException;
17
import java.lang.reflect.Method;
18
import java.util.regex.Pattern;
19

20
import mockit.Delegate;
21
import mockit.internal.util.StackTrace;
22
import mockit.internal.util.Utilities;
23

24
public final class MethodReflection {
25
    @NonNull
26
    public static final Pattern JAVA_LANG = Pattern.compile("java.lang.", Pattern.LITERAL);
1✔
27

28
    private MethodReflection() {
29
    }
30

31
    @Nullable
32
    public static <T> T invoke(@NonNull Class<?> theClass, @Nullable Object targetInstance, @NonNull String methodName,
33
            @NonNull Class<?>[] paramTypes, @NonNull Object... methodArgs) {
34
        Method method = findSpecifiedMethod(theClass, methodName, paramTypes);
×
35
        return invoke(targetInstance, method, methodArgs);
×
36
    }
37

38
    @NonNull
39
    private static Method findSpecifiedMethod(@NonNull Class<?> theClass, @NonNull String methodName,
40
            @NonNull Class<?>[] paramTypes) {
41
        while (true) {
42
            Method declaredMethod = findSpecifiedMethodInGivenClass(theClass, methodName, paramTypes);
1✔
43

44
            if (declaredMethod != null) {
1!
45
                return declaredMethod;
1✔
46
            }
47

48
            Class<?> superClass = theClass.getSuperclass();
×
49

50
            if (superClass == null || superClass == Object.class) {
×
51
                String paramTypesDesc = getParameterTypesDescription(paramTypes);
×
52
                throw new IllegalArgumentException("Specified method not found: " + methodName + paramTypesDesc);
×
53
            }
54

55
            // noinspection AssignmentToMethodParameter
56
            theClass = superClass;
×
57
        }
×
58
    }
59

60
    @Nullable
61
    private static Method findSpecifiedMethodInGivenClass(@NonNull Class<?> theClass, @NonNull String methodName,
62
            @NonNull Class<?>[] paramTypes) {
63
        for (Method declaredMethod : theClass.getDeclaredMethods()) {
1!
64
            if (declaredMethod.getName().equals(methodName)) {
1✔
65
                Class<?>[] declaredParameterTypes = declaredMethod.getParameterTypes();
1✔
66
                int firstRealParameter = indexOfFirstRealParameter(declaredParameterTypes, paramTypes);
1✔
67

68
                if (firstRealParameter >= 0
1✔
69
                        && matchesParameterTypes(declaredMethod.getParameterTypes(), paramTypes, firstRealParameter)) {
1✔
70
                    return declaredMethod;
1✔
71
                }
72
            }
73
        }
74

75
        return null;
×
76
    }
77

78
    @Nullable
79
    public static <T> T invokePublicIfAvailable(@NonNull Class<?> aClass, @Nullable Object targetInstance,
80
            @NonNull String methodName, @NonNull Class<?>[] parameterTypes, @NonNull Object... methodArgs) {
81
        Method publicMethod;
82
        try {
83
            publicMethod = aClass.getMethod(methodName, parameterTypes);
1✔
84
        } catch (NoSuchMethodException ignore) {
×
85
            return null;
×
86
        }
1✔
87

88
        return invoke(targetInstance, publicMethod, methodArgs);
1✔
89
    }
90

91
    @Nullable
92
    public static <T> T invokeWithCheckedThrows(@NonNull Class<?> theClass, @Nullable Object targetInstance,
93
            @NonNull String methodName, @NonNull Class<?>[] paramTypes, @NonNull Object... methodArgs)
94
            throws Throwable {
95
        Method method = findSpecifiedMethod(theClass, methodName, paramTypes);
1✔
96
        return invokeWithCheckedThrows(targetInstance, method, methodArgs);
1✔
97
    }
98

99
    @Nullable
100
    public static <T> T invoke(@Nullable Object targetInstance, @NonNull Method method, @NonNull Object... methodArgs) {
101
        Utilities.ensureThatMemberIsAccessible(method);
1✔
102

103
        try {
104
            // noinspection unchecked
105
            return (T) method.invoke(targetInstance, methodArgs);
1✔
106
        } catch (IllegalAccessException e) {
×
107
            throw new RuntimeException(e);
×
108
        } catch (IllegalArgumentException e) {
1✔
109
            StackTrace.filterStackTrace(e);
1✔
110
            throw new IllegalArgumentException("Failure to invoke method: " + method, e);
1✔
111
        } catch (InvocationTargetException e) {
1✔
112
            Throwable cause = e.getCause();
1✔
113

114
            if (cause instanceof Error) {
1!
115
                throw (Error) cause;
×
116
            } else if (cause instanceof RuntimeException) {
1!
117
                throw (RuntimeException) cause;
1✔
118
            } else {
119
                ThrowOfCheckedException.doThrow((Exception) cause);
×
120
                return null;
×
121
            }
122
        }
123
    }
124

125
    @Nullable
126
    public static <T> T invokeWithCheckedThrows(@Nullable Object targetInstance, @NonNull Method method,
127
            @NonNull Object... methodArgs) throws Throwable {
128
        Utilities.ensureThatMemberIsAccessible(method);
1✔
129

130
        try {
131
            // noinspection unchecked
132
            return (T) method.invoke(targetInstance, methodArgs);
1✔
133
        } catch (IllegalArgumentException e) {
1✔
134
            StackTrace.filterStackTrace(e);
1✔
135
            throw new IllegalArgumentException("Failure to invoke method: " + method, e);
1✔
136
        } catch (InvocationTargetException e) {
1✔
137
            throw e.getCause();
1✔
138
        }
139
    }
140

141
    @Nullable
142
    public static <T> T invoke(@NonNull Class<?> theClass, @Nullable Object targetInstance, @NonNull String methodName,
143
            @NonNull Object... methodArgs) {
144
        boolean staticMethod = targetInstance == null;
×
145
        Class<?>[] argTypes = getArgumentTypesFromArgumentValues(methodArgs);
×
146
        Method method = staticMethod ? findCompatibleStaticMethod(theClass, methodName, argTypes)
×
147
                : findCompatibleMethod(theClass, methodName, argTypes);
×
148

149
        if (staticMethod && !isStatic(method.getModifiers())) {
×
150
            throw new IllegalArgumentException(
×
151
                    "Attempted to invoke non-static method without an instance to invoke it on");
152
        }
153

154
        T result = invoke(targetInstance, method, methodArgs);
×
155
        return result;
×
156
    }
157

158
    @NonNull
159
    private static Method findCompatibleStaticMethod(@NonNull Class<?> theClass, @NonNull String methodName,
160
            @NonNull Class<?>[] argTypes) {
161
        Method methodFound = findCompatibleMethodInClass(theClass, methodName, argTypes);
×
162

163
        if (methodFound != null) {
×
164
            return methodFound;
×
165
        }
166

167
        String argTypesDesc = getParameterTypesDescription(argTypes);
×
168
        throw new IllegalArgumentException("No compatible static method found: " + methodName + argTypesDesc);
×
169
    }
170

171
    @NonNull
172
    public static Method findCompatibleMethod(@NonNull Class<?> theClass, @NonNull String methodName,
173
            @NonNull Class<?>[] argTypes) {
174
        Method methodFound = findCompatibleMethodIfAvailable(theClass, methodName, argTypes);
1✔
175

176
        if (methodFound != null) {
1!
177
            return methodFound;
1✔
178
        }
179

180
        String argTypesDesc = getParameterTypesDescription(argTypes);
×
181
        throw new IllegalArgumentException("No compatible method found: " + methodName + argTypesDesc);
×
182
    }
183

184
    @Nullable
185
    private static Method findCompatibleMethodIfAvailable(@NonNull Class<?> theClass, @NonNull String methodName,
186
            @NonNull Class<?>[] argTypes) {
187
        Method methodFound = null;
1✔
188

189
        while (true) {
190
            Method compatibleMethod = findCompatibleMethodInClass(theClass, methodName, argTypes);
1✔
191

192
            if (compatibleMethod != null && (methodFound == null
1!
193
                    || hasMoreSpecificTypes(compatibleMethod.getParameterTypes(), methodFound.getParameterTypes()))) {
×
194
                methodFound = compatibleMethod;
1✔
195
            }
196

197
            Class<?> superClass = theClass.getSuperclass();
1✔
198

199
            if (superClass == null || superClass == Object.class) {
1!
200
                break;
1✔
201
            }
202

203
            // noinspection AssignmentToMethodParameter
204
            theClass = superClass;
1✔
205
        }
1✔
206

207
        return methodFound;
1✔
208
    }
209

210
    @Nullable
211
    private static Method findCompatibleMethodInClass(@NonNull Class<?> theClass, @NonNull String methodName,
212
            @NonNull Class<?>[] argTypes) {
213
        Method found = null;
1✔
214
        Class<?>[] foundParamTypes = null;
1✔
215

216
        for (Method declaredMethod : theClass.getDeclaredMethods()) {
1✔
217
            if (declaredMethod.getName().equals(methodName)) {
1✔
218
                Class<?>[] declaredParamTypes = declaredMethod.getParameterTypes();
1✔
219
                int firstRealParameter = indexOfFirstRealParameter(declaredParamTypes, argTypes);
1✔
220

221
                if (firstRealParameter >= 0
1✔
222
                        && (matchesParameterTypes(declaredParamTypes, argTypes, firstRealParameter)
1✔
223
                                || acceptsArgumentTypes(declaredParamTypes, argTypes, firstRealParameter))
1!
224
                        && (foundParamTypes == null || hasMoreSpecificTypes(declaredParamTypes, foundParamTypes))) {
×
225
                    found = declaredMethod;
1✔
226
                    foundParamTypes = declaredParamTypes;
1✔
227
                }
228
            }
229
        }
230

231
        return found;
1✔
232
    }
233

234
    @NonNull
235
    public static Method findNonPrivateHandlerMethod(@NonNull Object handler) {
236
        Class<?> handlerClass = handler.getClass();
1✔
237
        Method nonPrivateMethod;
238

239
        do {
240
            nonPrivateMethod = findNonPrivateHandlerMethod(handlerClass);
1✔
241

242
            if (nonPrivateMethod != null) {
1✔
243
                break;
1✔
244
            }
245

246
            handlerClass = handlerClass.getSuperclass();
1✔
247
        } while (handlerClass != null && handlerClass != Object.class);
1!
248

249
        if (nonPrivateMethod == null) {
1✔
250
            throw new IllegalArgumentException("No non-private instance method found");
1✔
251
        }
252

253
        return nonPrivateMethod;
1✔
254
    }
255

256
    @Nullable
257
    private static Method findNonPrivateHandlerMethod(@NonNull Class<?> handlerClass) {
258
        Method[] declaredMethods = handlerClass.getDeclaredMethods();
1✔
259
        Method found = null;
1✔
260

261
        for (Method declaredMethod : declaredMethods) {
1✔
262
            int methodModifiers = declaredMethod.getModifiers();
1✔
263

264
            if (!isPrivate(methodModifiers) && !isStatic(methodModifiers)) {
1✔
265
                if (found != null) {
1✔
266
                    String methodType = Delegate.class.isAssignableFrom(handlerClass) ? "delegate"
1!
267
                            : "invocation handler";
1✔
268
                    throw new IllegalArgumentException("More than one candidate " + methodType + " method found: "
1✔
269
                            + methodSignature(found) + ", " + methodSignature(declaredMethod));
1✔
270
                }
271

272
                found = declaredMethod;
1✔
273
            }
274
        }
275

276
        return found;
1✔
277
    }
278

279
    @NonNull
280
    private static String methodSignature(@NonNull Method method) {
281
        String signature = JAVA_LANG.matcher(method.toGenericString()).replaceAll("");
1✔
282
        int p = signature.lastIndexOf('(');
1✔
283
        int q = signature.lastIndexOf('.', p);
1✔
284

285
        return signature.substring(q + 1);
1✔
286
    }
287
}
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