Skip to content

Commit

Permalink
Fix a class loading deadlock involving TypeAdapters. (#2740)
Browse files Browse the repository at this point in the history
* Fix a class loading deadlock involving `TypeAdapters`.

Fixes #2739.

* Remove deprecation of internal fields.

The idea was to discourage people from using these, but they have been there for
a long time and the deprecation isn't going to have much effect. Meanwhile the
deprecation required `@SuppressWarnings`, which was annoying.

Also move `JsonElementTypeFactory.ADAPTER` back into `TypeAdapters` so there is
no further circular dependency between the two classes. I think it was harmless
but it's easy enough to avoid.

* Omit unnecessary type qualificiation.
  • Loading branch information
eamonnmcmanus authored Sep 16, 2024
1 parent 48889db commit 6160932
Show file tree
Hide file tree
Showing 5 changed files with 12 additions and 46 deletions.
6 changes: 2 additions & 4 deletions gson/src/main/java/com/google/gson/Gson.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,7 @@
import com.google.gson.internal.bind.ArrayTypeAdapter;
import com.google.gson.internal.bind.CollectionTypeAdapterFactory;
import com.google.gson.internal.bind.DefaultDateTypeAdapter;
import com.google.gson.internal.bind.EnumTypeAdapter;
import com.google.gson.internal.bind.JsonAdapterAnnotationTypeAdapterFactory;
import com.google.gson.internal.bind.JsonElementTypeAdapter;
import com.google.gson.internal.bind.JsonTreeReader;
import com.google.gson.internal.bind.JsonTreeWriter;
import com.google.gson.internal.bind.MapTypeAdapterFactory;
Expand Down Expand Up @@ -325,7 +323,7 @@ public Gson() {
List<TypeAdapterFactory> factories = new ArrayList<>();

// built-in type adapters that cannot be overridden
factories.add(JsonElementTypeAdapter.FACTORY);
factories.add(TypeAdapters.JSON_ELEMENT_FACTORY);
factories.add(ObjectTypeAdapter.getFactory(objectToNumberStrategy));

// the excluder must precede all adapters that handle user-defined types
Expand Down Expand Up @@ -388,7 +386,7 @@ public Gson() {
factories.add(new MapTypeAdapterFactory(constructorConstructor, complexMapKeySerialization));
this.jsonAdapterFactory = new JsonAdapterAnnotationTypeAdapterFactory(constructorConstructor);
factories.add(jsonAdapterFactory);
factories.add(EnumTypeAdapter.FACTORY);
factories.add(TypeAdapters.ENUM_FACTORY);
factories.add(
new ReflectiveTypeAdapterFactory(
constructorConstructor,
Expand Down
6 changes: 3 additions & 3 deletions gson/src/main/java/com/google/gson/internal/Streams.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import com.google.gson.JsonNull;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSyntaxException;
import com.google.gson.internal.bind.JsonElementTypeAdapter;
import com.google.gson.internal.bind.TypeAdapters;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
Expand All @@ -43,7 +43,7 @@ public static JsonElement parse(JsonReader reader) throws JsonParseException {
try {
JsonToken unused = reader.peek();
isEmpty = false;
return JsonElementTypeAdapter.ADAPTER.read(reader);
return TypeAdapters.JSON_ELEMENT.read(reader);
} catch (EOFException e) {
/*
* For compatibility with JSON 1.5 and earlier, we return a JsonNull for
Expand All @@ -65,7 +65,7 @@ public static JsonElement parse(JsonReader reader) throws JsonParseException {

/** Writes the JSON element to the writer, recursively. */
public static void write(JsonElement element, JsonWriter writer) throws IOException {
JsonElementTypeAdapter.ADAPTER.write(writer, element);
TypeAdapters.JSON_ELEMENT.write(writer, element);
}

public static Writer writerForAppendable(Appendable appendable) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
import java.util.Map;

/** Adapter for enum classes (but not for the base class {@code java.lang.Enum}). */
public class EnumTypeAdapter<T extends Enum<T>> extends TypeAdapter<T> {
public static final TypeAdapterFactory FACTORY =
class EnumTypeAdapter<T extends Enum<T>> extends TypeAdapter<T> {
static final TypeAdapterFactory FACTORY =
new TypeAdapterFactory() {
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.internal.LazilyParsedNumber;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
Expand All @@ -33,11 +32,8 @@
import java.util.Map;

/** Adapter for {@link JsonElement} and subclasses. */
public class JsonElementTypeAdapter extends TypeAdapter<JsonElement> {
public static final JsonElementTypeAdapter ADAPTER = new JsonElementTypeAdapter();

public static final TypeAdapterFactory FACTORY =
TypeAdapters.newTypeHierarchyFactory(JsonElement.class, ADAPTER);
class JsonElementTypeAdapter extends TypeAdapter<JsonElement> {
static final JsonElementTypeAdapter ADAPTER = new JsonElementTypeAdapter();

private JsonElementTypeAdapter() {}

Expand Down
34 changes: 3 additions & 31 deletions gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java
Original file line number Diff line number Diff line change
Expand Up @@ -806,40 +806,12 @@ public void write(JsonWriter out, Locale value) throws IOException {

public static final TypeAdapterFactory LOCALE_FACTORY = newFactory(Locale.class, LOCALE);

/*
* The following adapter and factory fields have not been removed yet and are only deprecated
* for now because external projects might be using them, despite being part of Gson's internal
* implementation.
*/

/**
* @deprecated {@code TypeAdapters} is an internal Gson class. To obtain the adapter for {@link
* JsonElement} and subclasses use instead:
* <pre>{@code
* TypeAdapter<JsonElement> adapter = gson.getAdapter(JsonElement.class);
* }</pre>
*/
@Deprecated
public static final TypeAdapter<JsonElement> JSON_ELEMENT = JsonElementTypeAdapter.ADAPTER;

/**
* @deprecated {@code TypeAdapters} is an internal Gson class. To obtain the adapter for {@link
* JsonElement} and subclasses use instead:
* <pre>{@code
* TypeAdapter<JsonElement> adapter = gson.getAdapter(JsonElement.class);
* }</pre>
*/
@Deprecated
public static final TypeAdapterFactory JSON_ELEMENT_FACTORY = JsonElementTypeAdapter.FACTORY;
public static final TypeAdapterFactory JSON_ELEMENT_FACTORY =
newTypeHierarchyFactory(JsonElement.class, JSON_ELEMENT);

/**
* @deprecated {@code TypeAdapters} is an internal Gson class. To obtain the adapter for a
* specific enum class use instead:
* <pre>{@code
* TypeAdapter<MyEnum> adapter = gson.getAdapter(MyEnum.class);
* }</pre>
*/
@Deprecated public static final TypeAdapterFactory ENUM_FACTORY = EnumTypeAdapter.FACTORY;
public static final TypeAdapterFactory ENUM_FACTORY = EnumTypeAdapter.FACTORY;

@SuppressWarnings("TypeParameterNaming")
public static <TT> TypeAdapterFactory newFactory(
Expand Down

0 comments on commit 6160932

Please sign in to comment.