4040import java .lang .reflect .Field ;
4141import java .lang .reflect .InvocationTargetException ;
4242import java .util .ArrayList ;
43+ import java .util .Collection ;
4344import java .util .HashMap ;
4445import java .util .List ;
4546import java .util .logging .Level ;
@@ -198,9 +199,13 @@ public static Savable fromName(String className)
198199 * @throws ClassNotFoundException thrown if the class name is not in the classpath.
199200 * @throws SecurityException thrown if the filter rejects the class name.
200201 */
201- public static Savable fromName (String className , SavableClassFilter classFilter )
202- throws ClassNotFoundException , IllegalAccessException ,
203- InstantiationException , InvocationTargetException {
202+ public static Savable fromName (String className , SavableClassFilter classFilter )
203+ throws ClassNotFoundException , IllegalAccessException , InstantiationException , InvocationTargetException {
204+ return fromName (className , classFilter , null );
205+ }
206+
207+ public static Savable fromName (String className , SavableClassFilter classFilter , Collection <ClassLoader > additionalClassLoaders )
208+ throws ClassNotFoundException , IllegalAccessException , InstantiationException , InvocationTargetException {
204209 className = remapClass (className );
205210 if (classFilter == null ) {
206211 throw new NullPointerException ("classFilter" );
@@ -209,7 +214,7 @@ public static Savable fromName(String className, SavableClassFilter classFilter)
209214 throw new SecurityException ("Savable class rejected by filter: " + className );
210215 }
211216
212- Constructor noArgConstructor = findNoArgConstructor (className );
217+ Constructor noArgConstructor = findNoArgConstructor (className , additionalClassLoaders );
213218 noArgConstructor .setAccessible (true );
214219 try {
215220 return (Savable ) noArgConstructor .newInstance ();
@@ -226,6 +231,7 @@ public static Savable fromName(String className, SavableClassFilter classFilter)
226231 }
227232 }
228233
234+
229235 /**
230236 * @deprecated use {@link #fromName(java.lang.String)} instead
231237 */
@@ -240,6 +246,9 @@ public static Savable fromName(String className, List<ClassLoader> loaders) thro
240246 String newClassName = remapClass (className );
241247 synchronized (loaders ) {
242248 for (ClassLoader classLoader : loaders ) {
249+ if (classLoader == null ) {
250+ continue ;
251+ }
243252 final Class <?> loadedClass ;
244253 try {
245254 loadedClass = classLoader .loadClass (newClassName );
@@ -263,12 +272,35 @@ public static Savable fromName(String className, List<ClassLoader> loaders) thro
263272 * @return the pre-existing constructor (not null)
264273 */
265274 @ SuppressWarnings ("unchecked" )
266- private static Constructor findNoArgConstructor (String className )
275+ private static Constructor findNoArgConstructor (String className , Collection < ClassLoader > additionalClassLoaders )
267276 throws ClassNotFoundException , InstantiationException {
268- Class clazz = Class .forName (className );
277+ Class clazz = null ;
278+
279+ try {
280+ clazz = Class .forName (className );
281+ } catch (ClassNotFoundException e ) {
282+ if (additionalClassLoaders != null ) {
283+ for (ClassLoader classLoader : additionalClassLoaders ) {
284+ if (classLoader == null ) {
285+ continue ;
286+ }
287+ try {
288+ clazz = Class .forName (className , true , classLoader );
289+ break ;
290+ } catch (ClassNotFoundException ex ) {
291+ // ignore
292+ }
293+ }
294+ }
295+ if (clazz == null ) {
296+ throw e ;
297+ }
298+ }
299+
269300 if (!SavableClassUtil .isImplementingSavable (clazz )) {
270301 throw new InstantiationException ("Class " + className + " does not implement Savable." );
271302 }
303+
272304 Constructor result ;
273305 try {
274306 result = clazz .getDeclaredConstructor ();
0 commit comments