Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix failing to serialize Collection or Map with inaccessible construc…
…tor (#1902) * Remove UnsafeReflectionAccessor Revert #1218 Usage of sun.misc.Unsafe to change internal AccessibleObject.override field to suppress JPMS warnings goes against the intentions of the JPMS and does not work anymore in newer versions, see #1540. Therefore remove it and instead create a descriptive exception when making a member accessible fails. If necessary users can also still use `java` command line flags to open external modules. * Fix failing to serialize Collection or Map with inaccessible constructor Also remove tests which rely on Java implementation details. * Don't keep reference to access exception of ConstructorConstructor This also avoids a confusing stack trace, since the previously caught exception might have had a complete unrelated stack trace. * Remove Maven toolchain requirement * Address review feedback * Add back test for Security Manager
- Loading branch information
1 parent
0d9f6b6
commit b0595c5
Showing
14 changed files
with
287 additions
and
387 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
33 changes: 0 additions & 33 deletions
33
gson/src/main/java/com/google/gson/internal/reflect/PreJava9ReflectionAccessor.java
This file was deleted.
Oops, something went wrong.
54 changes: 0 additions & 54 deletions
54
gson/src/main/java/com/google/gson/internal/reflect/ReflectionAccessor.java
This file was deleted.
Oops, something went wrong.
66 changes: 66 additions & 0 deletions
66
gson/src/main/java/com/google/gson/internal/reflect/ReflectionHelper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package com.google.gson.internal.reflect; | ||
|
||
import com.google.gson.JsonIOException; | ||
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(); | ||
} | ||
} | ||
} |
Oops, something went wrong.