1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package javax.faces;
20
21 import javax.faces.application.ApplicationFactory;
22 import javax.faces.component.visit.VisitContextFactory;
23 import javax.faces.context.ExceptionHandlerFactory;
24 import javax.faces.context.ExternalContextFactory;
25 import javax.faces.context.FacesContext;
26 import javax.faces.context.FacesContextFactory;
27 import javax.faces.context.FlashFactory;
28 import javax.faces.context.PartialViewContextFactory;
29 import javax.faces.flow.FlowHandlerFactory;
30 import javax.faces.lifecycle.ClientWindowFactory;
31 import javax.faces.lifecycle.LifecycleFactory;
32 import javax.faces.render.RenderKitFactory;
33 import javax.faces.view.ViewDeclarationLanguageFactory;
34 import javax.faces.view.facelets.FaceletCacheFactory;
35 import javax.faces.view.facelets.TagHandlerDelegateFactory;
36 import java.lang.reflect.Constructor;
37 import java.lang.reflect.InvocationTargetException;
38 import java.lang.reflect.Method;
39 import java.security.AccessController;
40 import java.util.ArrayList;
41 import java.util.HashMap;
42 import java.util.HashSet;
43 import java.util.Iterator;
44 import java.util.List;
45 import java.util.Map;
46 import java.util.Set;
47 import java.util.concurrent.CopyOnWriteArrayList;
48 import java.util.logging.Level;
49 import java.util.logging.Logger;
50
51
52
53
54 public final class FactoryFinder
55 {
56 public static final String APPLICATION_FACTORY = "javax.faces.application.ApplicationFactory";
57 public static final String EXCEPTION_HANDLER_FACTORY = "javax.faces.context.ExceptionHandlerFactory";
58 public static final String EXTERNAL_CONTEXT_FACTORY = "javax.faces.context.ExternalContextFactory";
59 public static final String FACES_CONTEXT_FACTORY = "javax.faces.context.FacesContextFactory";
60 public static final String LIFECYCLE_FACTORY = "javax.faces.lifecycle.LifecycleFactory";
61 public static final String PARTIAL_VIEW_CONTEXT_FACTORY = "javax.faces.context.PartialViewContextFactory";
62 public static final String RENDER_KIT_FACTORY = "javax.faces.render.RenderKitFactory";
63 public static final String TAG_HANDLER_DELEGATE_FACTORY = "javax.faces.view.facelets.TagHandlerDelegateFactory";
64 public static final String VIEW_DECLARATION_LANGUAGE_FACTORY = "javax.faces.view.ViewDeclarationLanguageFactory";
65 public static final String VISIT_CONTEXT_FACTORY = "javax.faces.component.visit.VisitContextFactory";
66 public static final String FACELET_CACHE_FACTORY = "javax.faces.view.facelets.FaceletCacheFactory";
67 public static final String FLASH_FACTORY = "javax.faces.context.FlashFactory";
68 public static final String FLOW_HANDLER_FACTORY = "javax.faces.flow.FlowHandlerFactory";
69 public static final String CLIENT_WINDOW_FACTORY = "javax.faces.lifecycle.ClientWindowFactory";
70
71
72
73
74
75 private static Map<ClassLoader, Map<String, List<String>>> registeredFactoryNames
76 = new HashMap<ClassLoader, Map<String, List<String>>>();
77
78
79
80
81
82
83
84
85
86 private static Map<ClassLoader, Map<String, Object>> factories
87 = new HashMap<ClassLoader, Map<String, Object>>();
88
89 private static final Set<String> VALID_FACTORY_NAMES = new HashSet<String>();
90 private static final Map<String, Class<?>> ABSTRACT_FACTORY_CLASSES = new HashMap<String, Class<?>>();
91 private static final ClassLoader MYFACES_CLASSLOADER;
92
93 private static final String INJECTION_PROVIDER_INSTANCE = "oam.spi.INJECTION_PROVIDER_KEY";
94 private static final String INJECTED_BEAN_STORAGE_KEY = "org.apache.myfaces.spi.BEAN_ENTRY_STORAGE";
95 private static final String BEAN_ENTRY_CLASS_NAME = "org.apache.myfaces.cdi.dependent.BeanEntry";
96
97 private static final Logger LOGGER = Logger.getLogger(FactoryFinder.class.getName());
98
99 static
100 {
101 VALID_FACTORY_NAMES.add(APPLICATION_FACTORY);
102 VALID_FACTORY_NAMES.add(EXCEPTION_HANDLER_FACTORY);
103 VALID_FACTORY_NAMES.add(EXTERNAL_CONTEXT_FACTORY);
104 VALID_FACTORY_NAMES.add(FACES_CONTEXT_FACTORY);
105 VALID_FACTORY_NAMES.add(LIFECYCLE_FACTORY);
106 VALID_FACTORY_NAMES.add(PARTIAL_VIEW_CONTEXT_FACTORY);
107 VALID_FACTORY_NAMES.add(RENDER_KIT_FACTORY);
108 VALID_FACTORY_NAMES.add(TAG_HANDLER_DELEGATE_FACTORY);
109 VALID_FACTORY_NAMES.add(VIEW_DECLARATION_LANGUAGE_FACTORY);
110 VALID_FACTORY_NAMES.add(VISIT_CONTEXT_FACTORY);
111 VALID_FACTORY_NAMES.add(FACELET_CACHE_FACTORY);
112 VALID_FACTORY_NAMES.add(FLASH_FACTORY);
113 VALID_FACTORY_NAMES.add(FLOW_HANDLER_FACTORY);
114 VALID_FACTORY_NAMES.add(CLIENT_WINDOW_FACTORY);
115
116 ABSTRACT_FACTORY_CLASSES.put(APPLICATION_FACTORY, ApplicationFactory.class);
117 ABSTRACT_FACTORY_CLASSES.put(EXCEPTION_HANDLER_FACTORY, ExceptionHandlerFactory.class);
118 ABSTRACT_FACTORY_CLASSES.put(EXTERNAL_CONTEXT_FACTORY, ExternalContextFactory.class);
119 ABSTRACT_FACTORY_CLASSES.put(FACES_CONTEXT_FACTORY, FacesContextFactory.class);
120 ABSTRACT_FACTORY_CLASSES.put(LIFECYCLE_FACTORY, LifecycleFactory.class);
121 ABSTRACT_FACTORY_CLASSES.put(PARTIAL_VIEW_CONTEXT_FACTORY, PartialViewContextFactory.class);
122 ABSTRACT_FACTORY_CLASSES.put(RENDER_KIT_FACTORY, RenderKitFactory.class);
123 ABSTRACT_FACTORY_CLASSES.put(TAG_HANDLER_DELEGATE_FACTORY, TagHandlerDelegateFactory.class);
124 ABSTRACT_FACTORY_CLASSES.put(VIEW_DECLARATION_LANGUAGE_FACTORY, ViewDeclarationLanguageFactory.class);
125 ABSTRACT_FACTORY_CLASSES.put(VISIT_CONTEXT_FACTORY, VisitContextFactory.class);
126 ABSTRACT_FACTORY_CLASSES.put(FACELET_CACHE_FACTORY, FaceletCacheFactory.class);
127 ABSTRACT_FACTORY_CLASSES.put(FLASH_FACTORY, FlashFactory.class);
128 ABSTRACT_FACTORY_CLASSES.put(FLOW_HANDLER_FACTORY, FlowHandlerFactory.class);
129 ABSTRACT_FACTORY_CLASSES.put(CLIENT_WINDOW_FACTORY, ClientWindowFactory.class);
130 try
131 {
132 ClassLoader classLoader;
133 if (System.getSecurityManager() != null)
134 {
135 classLoader = (ClassLoader) AccessController.doPrivileged(new java.security.PrivilegedExceptionAction()
136 {
137 public Object run()
138 {
139 return FactoryFinder.class.getClassLoader();
140 }
141 });
142 }
143 else
144 {
145 classLoader = FactoryFinder.class.getClassLoader();
146 }
147
148 if (classLoader == null)
149 {
150 throw new FacesException("jsf api class loader cannot be identified", null);
151 }
152 MYFACES_CLASSLOADER = classLoader;
153 }
154 catch (Exception e)
155 {
156 throw new FacesException("jsf api class loader cannot be identified", e);
157 }
158 }
159
160
161
162 private static Object factoryFinderProviderFactoryInstance;
163
164 private static volatile boolean initialized = false;
165
166 private static void initializeFactoryFinderProviderFactory()
167 {
168 if (!initialized)
169 {
170 factoryFinderProviderFactoryInstance = _FactoryFinderProviderFactory.getInstance();
171 initialized = true;
172 }
173 }
174
175
176
177
178 FactoryFinder()
179 {
180 }
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213 public static Object getFactory(String factoryName) throws FacesException
214 {
215 if (factoryName == null)
216 {
217 throw new NullPointerException("factoryName may not be null");
218 }
219
220 initializeFactoryFinderProviderFactory();
221
222 if (factoryFinderProviderFactoryInstance == null)
223 {
224
225 return _getFactory(factoryName);
226 }
227 else
228 {
229 try
230 {
231
232 Object ffp = _FactoryFinderProviderFactory
233 .FACTORY_FINDER_PROVIDER_FACTORY_GET_FACTORY_FINDER_METHOD
234 .invoke(factoryFinderProviderFactoryInstance, null);
235
236
237 return _FactoryFinderProviderFactory
238 .FACTORY_FINDER_PROVIDER_GET_FACTORY_METHOD.invoke(ffp, factoryName);
239 }
240 catch (InvocationTargetException e)
241 {
242 Throwable targetException = e.getCause();
243 if (targetException instanceof NullPointerException)
244 {
245 throw (NullPointerException) targetException;
246 }
247 else if (targetException instanceof FacesException)
248 {
249 throw (FacesException) targetException;
250 }
251 else if (targetException instanceof IllegalArgumentException)
252 {
253 throw (IllegalArgumentException) targetException;
254 }
255 else if (targetException instanceof IllegalStateException)
256 {
257 throw (IllegalStateException) targetException;
258 }
259 else if (targetException == null)
260 {
261 throw new FacesException(e);
262 }
263 else
264 {
265 throw new FacesException(targetException);
266 }
267 }
268 catch (Exception e)
269 {
270
271 throw new FacesException(e);
272 }
273 }
274 }
275
276 private static Object _getFactory(String factoryName) throws FacesException
277 {
278 ClassLoader classLoader = getClassLoader();
279
280
281
282
283 Map<String, List<String>> factoryClassNames = null;
284 Map<String, Object> factoryMap = null;
285
286 synchronized (registeredFactoryNames)
287 {
288 factoryClassNames = registeredFactoryNames.get(classLoader);
289
290 if (factoryClassNames == null)
291 {
292 String message
293 = "No Factories configured for this Application. This happens if the faces-initialization "
294 + "does not work at all - make sure that you properly include all configuration "
295 + "settings necessary for a basic faces application "
296 + "and that all the necessary libs are included. Also check the logging output of your "
297 + "web application and your container for any exceptions!"
298 + "\nIf you did that and find nothing, the mistake might be due to the fact "
299 + "that you use some special web-containers which "
300 + "do not support registering context-listeners via TLD files and "
301 + "a context listener is not setup in your web.xml.\n"
302 + "A typical config looks like this;\n<listener>\n"
303 + " <listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>\n"
304 + "</listener>\n";
305 throw new IllegalStateException(message);
306 }
307
308 if (!factoryClassNames.containsKey(factoryName))
309 {
310 throw new IllegalArgumentException("no factory " + factoryName + " configured for this application.");
311 }
312
313 factoryMap = factories.get(classLoader);
314
315 if (factoryMap == null)
316 {
317 factoryMap = new HashMap<String, Object>();
318 factories.put(classLoader, factoryMap);
319 }
320 }
321
322 List beanEntryStorage;
323
324 synchronized (factoryClassNames)
325 {
326 beanEntryStorage = (List)factoryMap.get(INJECTED_BEAN_STORAGE_KEY);
327
328 if (beanEntryStorage == null)
329 {
330 beanEntryStorage = new CopyOnWriteArrayList();
331 factoryMap.put(INJECTED_BEAN_STORAGE_KEY, beanEntryStorage);
332 }
333 }
334
335 List<String> classNames;
336 Object factory;
337 Object injectionProvider;
338 synchronized (factoryClassNames)
339 {
340 factory = factoryMap.get(factoryName);
341 if (factory != null)
342 {
343 return factory;
344 }
345
346 classNames = factoryClassNames.get(factoryName);
347
348 injectionProvider = factoryMap.get(INJECTION_PROVIDER_INSTANCE);
349 }
350
351 if (injectionProvider == null)
352 {
353 injectionProvider = getInjectionProvider();
354 synchronized (factoryClassNames)
355 {
356 factoryMap.put(INJECTION_PROVIDER_INSTANCE, injectionProvider);
357 }
358 }
359
360
361 factory = newFactoryInstance(ABSTRACT_FACTORY_CLASSES.get(factoryName),
362 classNames.iterator(), classLoader, injectionProvider, beanEntryStorage);
363
364 synchronized (factoryClassNames)
365 {
366
367 if (factoryMap.get(factoryName) == null)
368 {
369 factoryMap.put(factoryName, factory);
370 }
371 }
372
373 return factory;
374 }
375
376 private static Object getInjectionProvider()
377 {
378 try
379 {
380
381
382
383
384
385
386 FacesContext facesContext = FacesContext.getCurrentInstance();
387 if (facesContext != null)
388 {
389 Object injectionProviderFactory =
390 _FactoryFinderProviderFactory.INJECTION_PROVIDER_FACTORY_GET_INSTANCE_METHOD
391 .invoke(_FactoryFinderProviderFactory.INJECTION_PROVIDER_CLASS);
392 Object injectionProvider =
393 _FactoryFinderProviderFactory.INJECTION_PROVIDER_FACTORY_GET_INJECTION_PROVIDER_METHOD
394 .invoke(injectionProviderFactory, facesContext.getExternalContext());
395 return injectionProvider;
396 }
397 }
398 catch (Exception e)
399 {
400 }
401 return null;
402 }
403
404 private static void injectAndPostConstruct(Object injectionProvider, Object instance, List injectedBeanStorage)
405 {
406 if (injectionProvider != null)
407 {
408 try
409 {
410 Object creationMetaData = _FactoryFinderProviderFactory.INJECTION_PROVIDER_INJECT_METHOD.invoke(
411 injectionProvider, instance);
412
413 addBeanEntry(instance, creationMetaData, injectedBeanStorage);
414
415 _FactoryFinderProviderFactory.INJECTION_PROVIDER_POST_CONSTRUCT_METHOD.invoke(
416 injectionProvider, instance, creationMetaData);
417 }
418 catch (Exception ex)
419 {
420 throw new FacesException(ex);
421 }
422 }
423 }
424
425 private static void preDestroy(Object injectionProvider, Object beanEntry)
426 {
427 if (injectionProvider != null)
428 {
429 try
430 {
431 _FactoryFinderProviderFactory.INJECTION_PROVIDER_PRE_DESTROY_METHOD.invoke(
432 injectionProvider, getInstance(beanEntry), getCreationMetaData(beanEntry));
433 }
434 catch (Exception ex)
435 {
436 throw new FacesException(ex);
437 }
438 }
439 }
440
441 private static Object getInstance(Object beanEntry)
442 {
443 try
444 {
445 Method getterMethod = getMethod(beanEntry, "getInstance");
446 return getterMethod.invoke(beanEntry);
447 }
448 catch (Exception e)
449 {
450 throw new IllegalStateException(e);
451 }
452 }
453
454 private static Object getCreationMetaData(Object beanEntry)
455 {
456 try
457 {
458 Method getterMethod = getMethod(beanEntry, "getCreationMetaData");
459 return getterMethod.invoke(beanEntry);
460 }
461 catch (Exception e)
462 {
463 throw new IllegalStateException(e);
464 }
465 }
466
467 private static Method getMethod(Object beanEntry, String methodName) throws NoSuchMethodException
468 {
469 return beanEntry.getClass().getDeclaredMethod(methodName);
470 }
471
472 private static void addBeanEntry(Object instance, Object creationMetaData, List injectedBeanStorage)
473 {
474 try
475 {
476 Class<?> beanEntryClass = _FactoryFinderProviderFactory.classForName(BEAN_ENTRY_CLASS_NAME);
477 Constructor beanEntryConstructor = beanEntryClass.getDeclaredConstructor(Object.class, Object.class);
478
479 Object result = beanEntryConstructor.newInstance(instance, creationMetaData);
480 injectedBeanStorage.add(result);
481 }
482 catch (Exception e)
483 {
484 throw new RuntimeException(e);
485 }
486 }
487
488 private static Object newFactoryInstance(Class<?> interfaceClass, Iterator<String> classNamesIterator,
489 ClassLoader classLoader, Object injectionProvider,
490 List injectedBeanStorage)
491 {
492 try
493 {
494 Object current = null;
495
496 while (classNamesIterator.hasNext())
497 {
498 String implClassName = classNamesIterator.next();
499 Class<?> implClass = null;
500 try
501 {
502 implClass = classLoader.loadClass(implClassName);
503 }
504 catch (ClassNotFoundException e)
505 {
506 implClass = MYFACES_CLASSLOADER.loadClass(implClassName);
507 }
508
509
510 if (!interfaceClass.isAssignableFrom(implClass))
511 {
512 throw new IllegalArgumentException("Class " + implClassName + " is no " + interfaceClass.getName());
513 }
514
515 if (current == null)
516 {
517
518 current = implClass.newInstance();
519 injectAndPostConstruct(injectionProvider, current, injectedBeanStorage);
520 }
521 else
522 {
523
524 try
525 {
526 Constructor<?> delegationConstructor = implClass.getConstructor(new Class[] { interfaceClass });
527
528 try
529 {
530
531 current = delegationConstructor.newInstance(new Object[] { current });
532 injectAndPostConstruct(injectionProvider, current, injectedBeanStorage);
533 }
534 catch (InstantiationException e)
535 {
536 throw new FacesException(e);
537 }
538 catch (IllegalAccessException e)
539 {
540 throw new FacesException(e);
541 }
542 catch (InvocationTargetException e)
543 {
544 throw new FacesException(e);
545 }
546 }
547 catch (NoSuchMethodException e)
548 {
549
550 current = implClass.newInstance();
551 injectAndPostConstruct(injectionProvider, current, injectedBeanStorage);
552 }
553 }
554 }
555
556 return current;
557 }
558 catch (ClassNotFoundException e)
559 {
560 throw new FacesException(e);
561 }
562 catch (InstantiationException e)
563 {
564 throw new FacesException(e);
565 }
566 catch (IllegalAccessException e)
567 {
568 throw new FacesException(e);
569 }
570 }
571
572 public static void setFactory(String factoryName, String implName)
573 {
574 if (factoryName == null)
575 {
576 throw new NullPointerException("factoryName may not be null");
577 }
578
579 initializeFactoryFinderProviderFactory();
580
581 if (factoryFinderProviderFactoryInstance == null)
582 {
583
584 _setFactory(factoryName, implName);
585 }
586 else
587 {
588 try
589 {
590
591 Object ffp = _FactoryFinderProviderFactory
592 .FACTORY_FINDER_PROVIDER_FACTORY_GET_FACTORY_FINDER_METHOD
593 .invoke(factoryFinderProviderFactoryInstance, null);
594
595
596 _FactoryFinderProviderFactory
597 .FACTORY_FINDER_PROVIDER_SET_FACTORY_METHOD.invoke(ffp, factoryName, implName);
598 }
599 catch (InvocationTargetException e)
600 {
601 Throwable targetException = e.getCause();
602 if (targetException instanceof NullPointerException)
603 {
604 throw (NullPointerException) targetException;
605 }
606 else if (targetException instanceof FacesException)
607 {
608 throw (FacesException) targetException;
609 }
610 else if (targetException instanceof IllegalArgumentException)
611 {
612 throw (IllegalArgumentException) targetException;
613 }
614 else if (targetException == null)
615 {
616 throw new FacesException(e);
617 }
618 else
619 {
620 throw new FacesException(targetException);
621 }
622 }
623 catch (Exception e)
624 {
625
626 throw new FacesException(e);
627 }
628
629 }
630 }
631
632 private static void _setFactory(String factoryName, String implName)
633 {
634 checkFactoryName(factoryName);
635
636 ClassLoader classLoader = getClassLoader();
637 Map<String, List<String>> factoryClassNames = null;
638 synchronized (registeredFactoryNames)
639 {
640 Map<String, Object> factories = FactoryFinder.factories.get(classLoader);
641
642 if (factories != null && factories.containsKey(factoryName))
643 {
644
645
646 return;
647 }
648
649 factoryClassNames = registeredFactoryNames.get(classLoader);
650
651 if (factoryClassNames == null)
652 {
653 factoryClassNames = new HashMap<String, List<String>>();
654 registeredFactoryNames.put(classLoader, factoryClassNames);
655 }
656 }
657
658 synchronized (factoryClassNames)
659 {
660 List<String> classNameList = factoryClassNames.get(factoryName);
661
662 if (classNameList == null)
663 {
664 classNameList = new ArrayList<String>();
665 factoryClassNames.put(factoryName, classNameList);
666 }
667
668 classNameList.add(implName);
669 }
670 }
671
672 public static void releaseFactories() throws FacesException
673 {
674 initializeFactoryFinderProviderFactory();
675
676 if (factoryFinderProviderFactoryInstance == null)
677 {
678
679 _releaseFactories();
680 }
681 else
682 {
683 try
684 {
685
686 Object ffp = _FactoryFinderProviderFactory
687 .FACTORY_FINDER_PROVIDER_FACTORY_GET_FACTORY_FINDER_METHOD
688 .invoke(factoryFinderProviderFactoryInstance, null);
689
690
691 _FactoryFinderProviderFactory.FACTORY_FINDER_PROVIDER_RELEASE_FACTORIES_METHOD.invoke(ffp, null);
692 }
693 catch (InvocationTargetException e)
694 {
695 Throwable targetException = e.getCause();
696 if (targetException instanceof FacesException)
697 {
698 throw (FacesException) targetException;
699 }
700 else if (targetException == null)
701 {
702 throw new FacesException(e);
703 }
704 else
705 {
706 throw new FacesException(targetException);
707 }
708 }
709 catch (Exception e)
710 {
711
712 throw new FacesException(e);
713 }
714
715 }
716 }
717
718 private static void _releaseFactories() throws FacesException
719 {
720 ClassLoader classLoader = getClassLoader();
721
722 Map<String, Object> factoryMap;
723
724 synchronized (registeredFactoryNames)
725 {
726 factoryMap = factories.remove(classLoader);
727
728
729
730 Map<String, List<String>> factoryClassNames = registeredFactoryNames.get(classLoader);
731 if (factoryClassNames != null)
732 {
733 factoryClassNames.clear();
734 }
735
736 registeredFactoryNames.remove(classLoader);
737 }
738
739 if (factoryMap != null)
740 {
741 Object injectionProvider = factoryMap.remove(INJECTION_PROVIDER_INSTANCE);
742 if (injectionProvider != null)
743 {
744 List injectedBeanStorage = (List)factoryMap.get(INJECTED_BEAN_STORAGE_KEY);
745
746 FacesException firstException = null;
747 for (Object entry : injectedBeanStorage)
748 {
749 try
750 {
751 preDestroy(injectionProvider, entry);
752 }
753 catch (FacesException e)
754 {
755 LOGGER.log(Level.SEVERE, "#preDestroy failed", e);
756
757 if (firstException == null)
758 {
759 firstException = e;
760 }
761 }
762 }
763 injectedBeanStorage.clear();
764
765 if (firstException != null)
766 {
767 throw firstException;
768 }
769 }
770 }
771 }
772
773 private static void checkFactoryName(String factoryName)
774 {
775 if (!VALID_FACTORY_NAMES.contains(factoryName))
776 {
777 throw new IllegalArgumentException("factoryName '" + factoryName + "'");
778 }
779 }
780
781 private static ClassLoader getClassLoader()
782 {
783 try
784 {
785 ClassLoader classLoader = null;
786 if (System.getSecurityManager() != null)
787 {
788 classLoader = (ClassLoader) AccessController.doPrivileged(new java.security.PrivilegedExceptionAction()
789 {
790 public Object run()
791 {
792 return Thread.currentThread().getContextClassLoader();
793 }
794 });
795 }
796 else
797 {
798 classLoader = Thread.currentThread().getContextClassLoader();
799 }
800
801 if (classLoader == null)
802 {
803 throw new FacesException("web application class loader cannot be identified", null);
804 }
805 return classLoader;
806 }
807 catch (Exception e)
808 {
809 throw new FacesException("web application class loader cannot be identified", e);
810 }
811 }
812 }