Ответ 1
Когда вы сталкиваетесь с "странным" исключением, предлагая, чтобы классы/методы/файлы/компоненты/теги отсутствовали или отличались, хотя они, по-видимому, явно включены в веб-приложение, например, ниже,
java.lang.ClassFormatError: Отсутствует атрибут кода в методе, который не является родным или абстрактным в файле класса javax/faces/webapp/FacesServlet
java.util.MissingResourceException: Не удается найти пакет javax.faces.LogStrings
com.sun.faces.vendor.WebContainerInjectionProvider нельзя отнести к com.sun.faces.spi.InjectionProvider
com.sun.faces.config.ConfigurationException: CONFIGURATION FAILED
The tag named inputFile from namespace http://xmlns.jcp.org/jsf/html has a null handler-class defined.
java.lang.NullPointerException в javax.faces.CurrentThreadToServletContext.getFallbackFactory
или когда вы сталкиваетесь с "странным" временем выполнения, таким как сломанные сеансы HTTP (jsessionid
отображается в URL-адресах по всему месту) и/или сломанная область видимости JSF (она ведет себя как область запроса) и/или сломанные ресурсы CSS/JS/image, тогда вероятность велика, что путь к классам среды выполнения Webapp загрязнен дублируемыми разными версиями JAR файлов.
В вашем конкретном случае с FacesServlet
это означает, что первый файл JAR, содержащий упомянутый класс, был найден в первый раз, является фактически "файлом JAR файла проекта", предназначенным для поставщиков решений (таких как разработчики, работающие в Mojarra и MyFaces). Он содержит файлы классов с только сигнатурами классов и методов, без каких-либо структур кода и файлов ресурсов. Именно это означает "отсутствующий атрибут кода". Это чисто предназначено для javadocs и компиляции.
Всегда отмечайте серверные библиотеки как provided
Все зависимости, отмеченные как Спецификации Java "в Maven и наличие суффикса -api
в идентификаторе артефакта - это эти API-интерфейсы. Их не должно быть в пуле классов. Вы должны всегда отмечать их <scope>provided</scope>
, если вам действительно нужно иметь его в своем пом. Хорошо известным примером является API Java EE (Web):
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version><!-- 6.0 or 7.0 or newer --></version>
<scope>provided</scope>
</dependency>
Если область provided
отсутствует, то этот JAR окажется в webapp /WEB-INF/lib
, что вызовет все проблемы, с которыми вы столкнулись сейчас. Этот JAR также содержит класс плана FacesServlet
.
В вашем конкретном случае у вас есть ненужная зависимость JSF API:
<dependency>
<groupId>javax.faces</groupId>
<artifactId>javax.faces-api</artifactId>
</dependency>
Это вызывает проблемы, поскольку в нем содержится класс FacesServlet
. Удаление его и использование API provided
Java EE (Web), как показано выше, должны решить его.
Tomcat как баскетбольный контейнер JSP/Servlet уже предоставляет JSP, Servlet и EL (и с 8 также WebSocket). Поэтому вы должны пометить как минимум jsp-api
, servlet-api
и el-api
как provided
. Tomcat не предоставляет JSF (и JSTL). Поэтому вам нужно будет установить его через webapp.
Полноценные серверы Java EE, такие как WildFly, TomEE, GlassFish, Payara, WebSphere и т.д., уже предоставляют весь API Java EE, включая JSF. Поэтому вам абсолютно не нужно устанавливать JSF через webapp. Это приведет только к конфликтам, если сервер уже предоставит другую версию и/или версию из коробки. Единственная зависимость, которая вам нужна, это javaee-web-api
точно так, как показано выше.
Установка JSF на Tomcat
Правильный способ установки JSF в Tomcat упоминается в нашей вики JSF - Установка JSF. Существует 2 реализации JSF, Mojarra и MyFaces. Вы должны выбрать один из них и не.
Установка Mojarra на Tomcat:
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.faces</artifactId>
<version><!-- Check https://javaserverfaces.github.io --></version>
</dependency>
Вы также можете проверить org.glassfish:javax.faces
репозиторий для текущей последней версии (в настоящее время 2.2.13
). См. Также собственные инструкции по установке Mojarra.
Установка MyFaces на Tomcat:
<dependency>
<groupId>org.apache.myfaces.core</groupId>
<artifactId>myfaces-api</artifactId>
<version><!-- Check http://myfaces.apache.org --></version>
</dependency>
<dependency>
<groupId>org.apache.myfaces.core</groupId>
<artifactId>myfaces-impl</artifactId>
<version><!-- Check http://myfaces.apache.org --></version>
</dependency>
Вы также можете проверить org.apache.myfaces.core:myfaces-bundle
репозиторий для текущей последней версии (в настоящее время 2.2.10
).
Обратите внимание, что Tomcat 6 как контейнер Servlet 2.5 поддерживает максимальный JSF 2.1. Не забудьте также установить JSTL. См. Также наш JSF wiki - Установка JSF.