11/* Copyright (c) 2008-2023, Nathan Sweet
22 * All rights reserved.
3- *
3+ *
44 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
55 * conditions are met:
6- *
6+ *
77 * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
88 * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
99 * disclaimer in the documentation and/or other materials provided with the distribution.
1010 * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived
1111 * from this software without specific prior written permission.
12- *
12+ *
1313 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
1414 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
1515 * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
@@ -49,6 +49,7 @@ public InstantiatorStrategy getFallbackInstantiatorStrategy () {
4949 }
5050
5151 public ObjectInstantiator newInstantiatorOf (final Class type ) {
52+
5253 if (!Util .isAndroid ) {
5354 // Use ReflectASM if the class is not a non-static member class.
5455 Class enclosingType = type .getEnclosingClass ();
@@ -61,8 +62,8 @@ public ObjectInstantiator newInstantiatorOf (final Class type) {
6162 public Object newInstance () {
6263 try {
6364 return access .newInstance ();
64- } catch (Exception ex ) {
65- throw new KryoException ( "Error constructing instance of class: " + className ( type ) , ex );
65+ } catch (Exception | InstantiationError ex ) {
66+ throw createInstantiationError ( type , ex );
6667 }
6768 }
6869 };
@@ -86,17 +87,17 @@ public Object newInstance () {
8687 try {
8788 return constructor .newInstance ();
8889 } catch (Exception ex ) {
89- throw new KryoException ( "Error constructing instance of class: " + className ( type ) , ex );
90+ throw createInstantiationError ( type , ex );
9091 }
9192 }
9293 };
9394 } catch (Exception ignored ) {
9495 }
9596
9697 if (fallbackStrategy == null ) {
97- if (type .isMemberClass () && !Modifier .isStatic (type .getModifiers ()))
98+ if (type .isMemberClass () && !Modifier .isStatic (type .getModifiers ())) {
9899 throw new KryoException ("Class cannot be created (non-static member class): " + className (type ));
99- else {
100+ } else {
100101 StringBuilder message = new StringBuilder ("Class cannot be created (missing no-arg constructor): " + className (type ));
101102 if (type .getSimpleName ().equals ("" )) {
102103 message
@@ -108,10 +109,29 @@ public Object newInstance () {
108109 .append ("2. Register a FieldSerializer for the containing class and call FieldSerializer\n " )
109110 .append ("setIgnoreSyntheticFields(false) on it. This is not safe but may be sufficient temporarily." );
110111 }
112+
113+ if (type .isInterface ()) {
114+ message .append (
115+ "\n Note: The type you are trying to serialize into is abstract (interface). Kryo will not be able to create an instance of it. Possible solutions:\n " )
116+ .append (
117+ "You can either use a class that implements the interface or use a custom ObjectInstantiator to create an instance." );
118+ }
119+
111120 throw new KryoException (message .toString ());
112121 }
113122 }
114123 // InstantiatorStrategy.
115124 return fallbackStrategy .newInstantiatorOf (type );
116125 }
126+
127+ private KryoException createInstantiationError (Class type , Throwable throwable ) {
128+ StringBuilder message = new StringBuilder ("Error constructing instance of class: " + className (type ));
129+ // Note: For Array and Primitive types the abstract bit is always set.
130+ if (!type .isArray () && !type .isPrimitive () && Modifier .isAbstract (type .getModifiers ())) {
131+ message .append (
132+ "\n Note: The type you are trying to serialize into is abstract. Kryo will not be able to create an instance of it. Possible solutions:\n " )
133+ .append ("You can either use a concrete subclass or use a custom ObjectInstantiator to create an instance." );
134+ }
135+ return new KryoException (message .toString (), throwable );
136+ }
117137}
0 commit comments