diff --git a/moshi/src/main/java/com/squareup/moshi/ClassJsonAdapter.java b/moshi/src/main/java/com/squareup/moshi/ClassJsonAdapter.java index 500b293..a149116 100644 --- a/moshi/src/main/java/com/squareup/moshi/ClassJsonAdapter.java +++ b/moshi/src/main/java/com/squareup/moshi/ClassJsonAdapter.java @@ -79,18 +79,11 @@ final class ClassJsonAdapter extends JsonAdapter { if (Modifier.isAbstract(rawType.getModifiers())) { throw new IllegalArgumentException("Cannot serialize abstract class " + rawType.getName()); } - try { - //noinspection unchecked if the Class.forName works, the cast will work. - Class metadataClass = - (Class) Class.forName("kotlin.Metadata"); - if (rawType.isAnnotationPresent(metadataClass)) { - throw new IllegalArgumentException("Cannot serialize Kotlin type " + rawType.getName() - + ". Reflective serialization of Kotlin classes without using kotlin-reflect has " - + "undefined and unexpected behavior. Please use KotlinJsonAdapter from the " - + "moshi-kotlin artifact or use code gen from the moshi-kotlin-codegen artifact."); - } - } catch (ClassNotFoundException ignored) { - + if (Util.isKotlin(rawType)) { + throw new IllegalArgumentException("Cannot serialize Kotlin type " + rawType.getName() + + ". Reflective serialization of Kotlin classes without using kotlin-reflect has " + + "undefined and unexpected behavior. Please use KotlinJsonAdapter from the " + + "moshi-kotlin artifact or use code gen from the moshi-kotlin-codegen artifact."); } ClassFactory classFactory = ClassFactory.get(rawType); diff --git a/moshi/src/main/java/com/squareup/moshi/internal/Util.java b/moshi/src/main/java/com/squareup/moshi/internal/Util.java index 2480744..babd6e9 100644 --- a/moshi/src/main/java/com/squareup/moshi/internal/Util.java +++ b/moshi/src/main/java/com/squareup/moshi/internal/Util.java @@ -35,7 +35,6 @@ import java.lang.reflect.WildcardType; import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.HashSet; import java.util.LinkedHashSet; import java.util.NoSuchElementException; import java.util.Set; @@ -49,15 +48,18 @@ public final class Util { public static final Set NO_ANNOTATIONS = Collections.emptySet(); public static final Type[] EMPTY_TYPE_ARRAY = new Type[] {}; @Nullable private static final Class DEFAULT_CONSTRUCTOR_MARKER; + @Nullable private static final Class METADATA; static { - Class clazz; + Class metadata = null; + Class defaultConstructorMarker = null; try { - clazz = Class.forName("kotlin.jvm.internal.DefaultConstructorMarker"); - } catch (ClassNotFoundException e) { - clazz = null; + metadata = (Class) Class.forName("kotlin.Metadata"); + defaultConstructorMarker = Class.forName("kotlin.jvm.internal.DefaultConstructorMarker"); + } catch (ClassNotFoundException ignored) { } - DEFAULT_CONSTRUCTOR_MARKER = clazz; + METADATA = metadata; + DEFAULT_CONSTRUCTOR_MARKER = defaultConstructorMarker; } private Util() { @@ -171,7 +173,7 @@ public final class Util { } public static Type resolve(Type context, Class contextRawType, Type toResolve) { - return resolve(context, contextRawType, toResolve, new HashSet()); + return resolve(context, contextRawType, toResolve, new LinkedHashSet()); } private static Type resolve(Type context, Class contextRawType, Type toResolve, @@ -553,6 +555,10 @@ public final class Util { } } + public static boolean isKotlin(Class targetClass) { + return METADATA != null && targetClass.isAnnotationPresent(METADATA); + } + /** * Reflectively looks up the defaults constructor of a kotlin class. *