@@ -66,7 +66,7 @@ public class IndexItem<A extends Annotation> {
6666 * @return the annotation values
6767 */
6868 public A annotation () {
69- return proxy (annotation , loader , map );
69+ return proxy (annotation , loader , className , map );
7070 }
7171
7272 /**
@@ -80,7 +80,8 @@ public String className() {
8080
8181 @ SuppressWarnings ("unchecked" )
8282 private static <A extends Annotation > A proxy (final Class <A > annotation ,
83- final ClassLoader loader , final Map <Object , Object > map )
83+ final ClassLoader loader , final String className ,
84+ final Map <Object , Object > map )
8485 {
8586 return (A ) Proxy .newProxyInstance (loader , new Class <?>[] { annotation },
8687 new InvocationHandler () {
@@ -98,7 +99,7 @@ public Object invoke(Object proxy, Method method, Object[] args)
9899 value = map .get (name );
99100 final Class <?> expectedType = method .getReturnType ();
100101 if (!expectedType .isAssignableFrom (value .getClass ())) {
101- value = adapt (value , loader , expectedType );
102+ value = adapt (value , loader , expectedType , className );
102103 }
103104 }
104105 else if (name .equals ("toString" ) &&
@@ -147,7 +148,7 @@ else if (name.equals("equals") && args != null && args.length == 1) {
147148 }
148149
149150 private static Object adapt (final Object o , final ClassLoader loader ,
150- final Class <?> expectedType )
151+ final Class <?> expectedType , final String className )
151152 {
152153 if (o == null ) {
153154 return null ;
@@ -191,7 +192,7 @@ else if (expectedType == Class.class) {
191192 return loader .loadClass ((String ) o );
192193 }
193194 catch (Throwable t ) {
194- throw new ClassCastException ( t . getMessage () );
195+ throw cce ( o , expectedType , className , t );
195196 }
196197 }
197198 else if (expectedType .isArray ()) {
@@ -201,7 +202,7 @@ else if (expectedType.isArray()) {
201202 int length = list .size ();
202203 Object array = Array .newInstance (type , length );
203204 for (int i = 0 ; i < length ; i ++) {
204- Array .set (array , i , adapt (list .get (i ), loader , type ));
205+ Array .set (array , i , adapt (list .get (i ), loader , type , className ));
205206 }
206207 return array ;
207208 }
@@ -214,17 +215,30 @@ else if (Enum.class.isAssignableFrom(expectedType)) {
214215 return loader .loadClass (enumName ).getField (constName ).get (null );
215216 }
216217 catch (Throwable t ) {
217- throw new ClassCastException ( t . getMessage () );
218+ throw cce ( o , expectedType , className , t );
218219 }
219220 }
220221 else if (Annotation .class .isAssignableFrom (expectedType )) {
221222 @ SuppressWarnings ("unchecked" )
222223 final Class <Annotation > annotation = (Class <Annotation >) expectedType ;
223224 @ SuppressWarnings ("unchecked" )
224225 final Map <Object , Object > map = (Map <Object , Object >) o ;
225- return proxy (annotation , loader , map );
226+ return proxy (annotation , loader , className , map );
226227 }
227- throw new ClassCastException ("Cannot cast object of type " +
228- o .getClass ().getName () + " to " + expectedType .getName ());
228+ throw cce (o , expectedType , className , null );
229229 }
230+
231+ private static ClassCastException cce (final Object o ,
232+ final Class <?> expectedType , final String className , final Throwable cause )
233+ {
234+ final String oType = o == null ? "<null>" : o .getClass ().getName ();
235+ final String eType =
236+ expectedType == null ? "<null>" : expectedType .getName ();
237+ final ClassCastException cce =
238+ new ClassCastException (className + ": cannot cast object of type " +
239+ oType + " to " + eType );
240+ if (cause != null ) cce .initCause (cause );
241+ return cce ;
242+ }
243+
230244}
0 commit comments