@@ -116,36 +116,49 @@ public class ClassUtils
116116 }
117117
118118 /**
119- * Tries a Class.loadClass with the context class loader of the current thread first and automatically falls back to
120- * the ClassUtils class loader (i.e. the loader of the myfaces.jar lib) if necessary .
121- *
119+ * Tries {@link Class#forName(String, boolean, ClassLoader)} with the context class loader first, then
120+ * {@code fallbackLoader} (e.g. the ClassUtils defining module) if the type is not found .
121+ *
122122 * @param type
123123 * fully qualified name of a non-primitive non-array class
124+ * @param fallbackLoader
125+ * loader used when the context class loader cannot resolve {@code type}; if {@code null}, no fallback
124126 * @return the corresponding Class
125127 * @throws NullPointerException
126128 * if type is null
127129 * @throws ClassNotFoundException
130+ * if the type cannot be resolved
128131 */
129- public static <T > Class <T > classForName (String type ) throws ClassNotFoundException
132+ public static <T > Class <T > classForName (String type , ClassLoader fallbackLoader ) throws ClassNotFoundException
130133 {
131134 Assert .notNull (type , "type" );
132-
135+
133136 try
134137 {
135- // Try WebApp ClassLoader first
136138 return (Class <T >) Class .forName (type ,
137- false , // do not initialize for faster startup
139+ false ,
138140 getContextClassLoader ());
139141 }
140142 catch (ClassNotFoundException ignore )
141143 {
142- // fallback: Try ClassLoader for ClassUtils (i.e. the myfaces.jar lib)
144+ if (fallbackLoader == null )
145+ {
146+ throw ignore ;
147+ }
143148 return (Class <T >) Class .forName (type ,
144- false , // do not initialize for faster startup
145- ClassUtils . class . getClassLoader () );
149+ false ,
150+ fallbackLoader );
146151 }
147152 }
148153
154+ /**
155+ * Same as {@link #classForName(String, ClassLoader)} using {@code ClassUtils.class.getClassLoader()} as fallback.
156+ */
157+ public static <T > Class <T > classForName (String type ) throws ClassNotFoundException
158+ {
159+ return classForName (type , ClassUtils .class .getClassLoader ());
160+ }
161+
149162 /**
150163 * Same as {@link #classForName(String)}, but throws a RuntimeException (FacesException) instead of a
151164 * ClassNotFoundException.
@@ -367,22 +380,62 @@ public static Object newInstance(String type) throws FacesException
367380 {
368381 return null ;
369382 }
370- return newInstance (simpleClassForName (type ));
383+ return newInstance (type , ClassUtils .class .getClassLoader ());
384+ }
385+
386+ /**
387+ * Like {@link #newInstance(String)} but uses {@code fallbackLoader} when resolving the class name (MYFACES-4639).
388+ */
389+ public static Object newInstance (String type , ClassLoader fallbackLoader ) throws FacesException
390+ {
391+ if (type == null )
392+ {
393+ return null ;
394+ }
395+ try
396+ {
397+ return newInstance (classForName (type , fallbackLoader ));
398+ }
399+ catch (ClassNotFoundException e )
400+ {
401+ log .log (Level .SEVERE , "Class " + type + " not found" , e );
402+ throw new FacesException (e );
403+ }
371404 }
372405
373406 public static Object newInstance (String type , Class <?> expectedType ) throws FacesException
374407 {
375- return newInstance (type , expectedType == null ? null : new Class [] { expectedType });
408+ return newInstance (type , expectedType , ClassUtils .class .getClassLoader ());
409+ }
410+
411+ public static Object newInstance (String type , Class <?> expectedType , ClassLoader fallbackLoader )
412+ throws FacesException
413+ {
414+ return newInstance (type , expectedType == null ? null : new Class [] { expectedType }, fallbackLoader );
376415 }
377416
378417 public static Object newInstance (String type , Class <?>[] expectedTypes )
418+ {
419+ return newInstance (type , expectedTypes , ClassUtils .class .getClassLoader ());
420+ }
421+
422+ public static Object newInstance (String type , Class <?>[] expectedTypes , ClassLoader fallbackLoader )
379423 {
380424 if (type == null )
381425 {
382426 return null ;
383427 }
384428
385- Class <?> clazzForName = simpleClassForName (type );
429+ Class <?> clazzForName ;
430+ try
431+ {
432+ clazzForName = classForName (type , fallbackLoader );
433+ }
434+ catch (ClassNotFoundException e )
435+ {
436+ log .log (Level .SEVERE , "Class " + type + " not found" , e );
437+ throw new FacesException (e );
438+ }
386439
387440 if (expectedTypes != null )
388441 {
0 commit comments