blob: 97230ff6f503609164ec7e0d6cbcbe7edf6e87e7 [file] [log] [blame]
package com.google.gson.internal.reflect;
import com.google.gson.JsonIOException;
import com.google.gson.internal.GsonBuildConfig;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
public class ReflectionHelper {
private ReflectionHelper() { }
/**
* Tries making the field accessible, wrapping any thrown exception in a
* {@link JsonIOException} with descriptive message.
*
* @param field field to make accessible
* @throws JsonIOException if making the field accessible fails
*/
public static void makeAccessible(Field field) throws JsonIOException {
try {
field.setAccessible(true);
} catch (Exception exception) {
throw new JsonIOException("Failed making field '" + field.getDeclaringClass().getName() + "#"
+ field.getName() + "' accessible; either change its visibility or write a custom "
+ "TypeAdapter for its declaring type", exception);
}
}
/**
* Creates a string representation for a constructor.
* E.g.: {@code java.lang.String#String(char[], int, int)}
*/
private static String constructorToString(Constructor<?> constructor) {
StringBuilder stringBuilder = new StringBuilder(constructor.getDeclaringClass().getName())
.append('#')
.append(constructor.getDeclaringClass().getSimpleName())
.append('(');
Class<?>[] parameters = constructor.getParameterTypes();
for (int i = 0; i < parameters.length; i++) {
if (i > 0) {
stringBuilder.append(", ");
}
stringBuilder.append(parameters[i].getSimpleName());
}
return stringBuilder.append(')').toString();
}
/**
* Tries making the constructor accessible, returning an exception message
* if this fails.
*
* @param constructor constructor to make accessible
* @return exception message; {@code null} if successful, non-{@code null} if
* unsuccessful
*/
public static String tryMakeAccessible(Constructor<?> constructor) {
try {
constructor.setAccessible(true);
return null;
} catch (Exception exception) {
return "Failed making constructor '" + constructorToString(constructor) + "' accessible; "
+ "either change its visibility or write a custom InstanceCreator or TypeAdapter for its declaring type: "
// Include the message since it might contain more detailed information
+ exception.getMessage();
}
}
public static RuntimeException createExceptionForUnexpectedIllegalAccess(IllegalAccessException exception) {
throw new RuntimeException("Unexpected IllegalAccessException occurred (Gson " + GsonBuildConfig.VERSION + "). "
+ "Certain ReflectionAccessFilter features require Java >= 9 to work correctly. If you are not using "
+ "ReflectionAccessFilter, report this to the Gson maintainers.",
exception);
}
}