New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add GsonBuilder.disableJdkUnsafe()
#1904
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -48,9 +48,11 @@ | |
*/ | ||
public final class ConstructorConstructor { | ||
private final Map<Type, InstanceCreator<?>> instanceCreators; | ||
private final boolean useJdkUnsafe; | ||
|
||
public ConstructorConstructor(Map<Type, InstanceCreator<?>> instanceCreators) { | ||
public ConstructorConstructor(Map<Type, InstanceCreator<?>> instanceCreators, boolean useJdkUnsafe) { | ||
this.instanceCreators = instanceCreators; | ||
this.useJdkUnsafe = useJdkUnsafe; | ||
} | ||
|
||
public <T> ObjectConstructor<T> get(TypeToken<T> typeToken) { | ||
|
@@ -92,7 +94,7 @@ public <T> ObjectConstructor<T> get(TypeToken<T> typeToken) { | |
} | ||
|
||
// finally try unsafe | ||
return newUnsafeAllocator(type, rawType); | ||
return newUnsafeAllocator(rawType); | ||
} | ||
|
||
private <T> ObjectConstructor<T> newDefaultConstructor(Class<? super T> rawType) { | ||
|
@@ -233,21 +235,32 @@ private <T> ObjectConstructor<T> newDefaultImplementationConstructor( | |
return null; | ||
} | ||
|
||
private <T> ObjectConstructor<T> newUnsafeAllocator( | ||
final Type type, final Class<? super T> rawType) { | ||
return new ObjectConstructor<T>() { | ||
private final UnsafeAllocator unsafeAllocator = UnsafeAllocator.create(); | ||
@SuppressWarnings("unchecked") | ||
@Override public T construct() { | ||
try { | ||
Object newInstance = unsafeAllocator.newInstance(rawType); | ||
return (T) newInstance; | ||
} catch (Exception e) { | ||
throw new RuntimeException(("Unable to invoke no-args constructor for " + type + ". " | ||
+ "Registering an InstanceCreator with Gson for this type may fix this problem."), e); | ||
private <T> ObjectConstructor<T> newUnsafeAllocator(final Class<? super T> rawType) { | ||
if (useJdkUnsafe) { | ||
return new ObjectConstructor<T>() { | ||
private final UnsafeAllocator unsafeAllocator = UnsafeAllocator.create(); | ||
@SuppressWarnings("unchecked") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While you are here, could you reduce the scope of this?
|
||
@Override public T construct() { | ||
try { | ||
Object newInstance = unsafeAllocator.newInstance(rawType); | ||
return (T) newInstance; | ||
} catch (Exception e) { | ||
throw new RuntimeException(("Unable to create instance of " + rawType + ". " | ||
+ "Registering an InstanceCreator or a TypeAdapter for this type, or adding a no-args " | ||
+ "constructor may fix this problem."), e); | ||
} | ||
} | ||
} | ||
}; | ||
}; | ||
} else { | ||
final String exceptionMessage = "Unable to create instance of " + rawType + "; usage of JDK Unsafe " | ||
+ "is disabled. Registering an InstanceCreator or a TypeAdapter for this type, adding a no-args " | ||
+ "constructor, or enabling usage of JDK Unsafe may fix this problem."; | ||
return new ObjectConstructor<T>() { | ||
@Override public T construct() { | ||
throw new JsonIOException(exceptionMessage); | ||
} | ||
}; | ||
} | ||
} | ||
|
||
@Override public String toString() { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -84,4 +84,27 @@ public void testTransientFieldExclusion() { | |
static class HasTransients { | ||
transient String a = "a"; | ||
} | ||
|
||
public void testDisableJdkUnsafe() { | ||
Gson gson = new GsonBuilder() | ||
.disableJdkUnsafe() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Very nitpicky comment here, but these continuation lines should be indented +4 according to Google Java style. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No worries, such comments are fine |
||
.create(); | ||
try { | ||
gson.fromJson("{}", ClassWithoutNoArgsConstructor.class); | ||
fail("Expected exception"); | ||
} catch (JsonIOException expected) { | ||
assertEquals( | ||
"Unable to create instance of class com.google.gson.GsonBuilderTest$ClassWithoutNoArgsConstructor; " | ||
+ "usage of JDK Unsafe is disabled. Registering an InstanceCreator or a TypeAdapter for this type, " | ||
+ "adding a no-args constructor, or enabling usage of JDK Unsafe may fix this problem.", | ||
expected.getMessage() | ||
); | ||
} | ||
} | ||
|
||
private static class ClassWithoutNoArgsConstructor { | ||
@SuppressWarnings("unused") | ||
public ClassWithoutNoArgsConstructor(String s) { | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you start a new paragraph on the next line rather than
<br>
? Or just leave out<br>
.