java.lang.IllegalArgumentException:javax.faces.context.ExceptionHandlerFactory

java.lang.IllegalArgumentException: javax.faces.context.ExceptionHandlerFactory

問題

Eclipse IDEで、JSF 2.0 WebアプリケーションをTomcat 6.0.26にデプロイしているときに、次の例外が発生し、Tomcatサーバーの起動に失敗しました。

P.S Both jsf-api-2.1.0-b03.jar and jsf-impl-2.1.0-b03.jar libraries are included in the project classpath.

INFO: Unsanitized stacktrace from failed start...
java.lang.IllegalArgumentException: javax.faces.context.ExceptionHandlerFactory
    at javax.faces.FactoryFinder.validateFactoryName(FactoryFinder.java:630)
    at javax.faces.FactoryFinder.setFactory(FactoryFinder.java:287)
    ...
SEVERE: Critical error during deployment:
com.sun.faces.config.ConfigurationException:
CONFIGURATION FAILED! javax.faces.context.ExceptionHandlerFactory
    ...
Caused by: java.lang.IllegalArgumentException: javax.faces.context.ExceptionHandlerFactory
    at javax.faces.FactoryFinder.validateFactoryName(FactoryFinder.java:630)
    ...

溶液

Eclipseデバッグモードで、ソースコードを掘り下げて、IllegalArgumentExceptionがFactoryFinderのgetFactory()メソッドによってスローされることを確認します。

FactoryFinder.java

 /*
 * @throws IllegalArgumentException if factoryName does not
 *                                  identify a standard JavaServer Faces factory name
 * @throws IllegalStateException    if there is no configured factory
 *                                  implementation class for the specified factory name
 * @throws NullPointerException     if factoryname
 *                                  is null
 */

 public static Object getFactory(String factoryName)
         throws FacesException {

        validateFactoryName(factoryName);
        //...
 }

IllegalArgumentExceptionは、ファクターファインダーが新しいJSF2.0ExceptionHandlerFactoryのファクトリ名を認識しないことを文書化しました。

何千回ものテストと試行を行った後、最終的に、根本的な原因は、プロジェクトクラスパスに含まれているjavaee.jarにあることがわかりました。 javaee.jarの内部を見ると、JSF 1.2 APIのセットも含まれています。Tomcatが、新しいJSF 2.0APIではなくこのJSF1.2APIを選択しているようです。

プロジェクトのクラスパスからjavaee.jarを削除すると、JSF 2.0WebアプリケーションがTomcatで正常に起動して実行できるようになります。