JSF & Primefaces NoClassDefFoundError
Хорошо, ребята. После 3 часов борьбы я решил опубликовать вопрос здесь, так как я не могу решить это.
Давайте перейдем к делу.
У меня есть веб-проект NetBeans, выполненный с PrimeFaces 3. Он работает правильно, никаких проблем.
Но мне нужно создать корпоративное приложение, использующее этот веб-проект в качестве веб-модуля.
У меня уже есть проект EE с почти завершенной частью EJB, поэтому я начал "объединять" два проекта, копируя веб-страницы в военную часть проекта Enterprise и переписывая Managed Beans.
Но все стало грязно, поэтому мне пришлось внести некоторые изменения.
Я напишу код из 2 файлов в разных версиях (помните, что этот код работает в одном веб-проекте!):
- JSF PAGE -
[cut]
<p:dialog id="loginDialog" header="Login" widgetVar="loginDialog" showEffect="fade" hideEffect="fade" position="center" draggable="false" resizable="false" height="220" width="300" modal="true" showHeader="false">
<h:form id="loginForm">
<br/>
Username: <br/><p:inputText id="username" value="#{loginBean.username}" required="true" requiredMessage="random error message"/><br/><br/>
Password: <br/><p:password id="password" value="#{loginBean.password}" required="true" requiredMessage="random error message"/><br/><br/>
<p:commandButton value="Login" actionListener="#{loginBean.doLogin}" oncomplete="handleLoginRequest(xhr, status, args)" ajax="true" update=":growl, :loginForm, :userPanel"/> <p:commandButton value="Cancel" type="button" onclick="loginDialog.hide()" />
</h:form><br/>
</p:dialog>
[cut]
- управляемый боб -
[cut]
public void doLogin(ActionEvent ae) {
user = loginUser.doLogin(username, password);
loggedIn = false;
FacesMessage msg;
RequestContext context = RequestContext.getCurrentInstance();
if (user != null) {
msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Welcome " + user.getUsername(), user.getUsername());
loggedIn = true;
} else {
msg = new FacesMessage(FacesMessage.SEVERITY_WARN, "Login failed", "Incorrect credentials");
}
FacesContext.getCurrentInstance().addMessage(null, msg);
context.addCallbackParam("loggedIn", loggedIn);
}
[cut]
Даже если этот код работает в моем веб-проекте, "перемещение" его в полное EE-приложение приводит меня к ошибке:
Класс ManagedBeans.LoginBean не имеет свойства doLogin.
Итак, предполагая, что проблема вызвана подписью doLogin (она принимает один параметр, но на странице JSF вызывается без него), и, несмотря на то, что именно так компонент используется в документах PrimeFaces, я просто изменил это в:
- JSF PAGE -
[cut]
<p:dialog id="loginDialog" header="Login" widgetVar="loginDialog" showEffect="fade" hideEffect="fade" position="center" draggable="false" resizable="false" height="220" width="300" modal="true" showHeader="false">
<h:form id="loginForm">
<br/>
Username: <br/><p:inputText id="username" value="#{loginBean.username}" required="true" requiredMessage="random error message"/><br/><br/>
Password: <br/><p:password id="password" value="#{loginBean.password}" required="true" requiredMessage="random error message"/><br/><br/>
<p:commandButton value="Login" action="#{loginBean.doLogin()}" oncomplete="handleLoginRequest(xhr, status, args)" ajax="true" update=":growl, :loginForm, :userPanel"/> <p:commandButton value="Cancel" type="button" onclick="loginDialog.hide()" />
</h:form><br/>
</p:dialog>
[cut]
- управляемый боб -
[cut]
public void doLogin() {
user = loginUser.doLogin(username, password);
loggedIn = false;
FacesMessage msg;
RequestContext context = RequestContext.getCurrentInstance();
[cut]
Поэтому я изменил сигнатуру метода и действие commandButton.
Делая эти изменения, кажется, что предыдущая ошибка исчезла.. но..
java.lang.NoClassDefFoundError: org / primefaces / context / RequestContext
Да, теперь у меня есть этот.
Просто чтобы прояснить ситуацию, библиотека импортируется, и все в порядке.NETBeans может правильно импортировать из org.primefaces. *, Поэтому я предполагаю, что файл jar загружен.
Но тут приходит странная вещь.
После удаления PrimeFaces из библиотек и импорта нового jar-файла (того же, что и раньше, он просто находится в другом каталоге) он, похоже, работает.
Страница загружается без проблем.
Но это продолжается только до следующего развертывания, потому что новое развертывание приведет меня к тому же NoDefClassFoundError, что и раньше.
Это довольно случайная вещь, потому что она решается после некоторой игры с путями к библиотекам, но ни один из них не подходит для более чем одного развертывания.
Я не знаю, что делать, потому что все довольно странно.
Иногда он просто загружает страницу с желтым предупреждением о том, что он не может найти библиотеку для пространства имен http://primefaces.org/ui (или что-то в этом роде).
Я прошу прощения за длину вопроса, но довольно сложно объяснить, что я вижу.
Есть ли кто-нибудь, кто может указать мне на решение?
1 ответ
Обе проблемы имеют абсолютно одинаковую причину: JAR-файл PrimeFaces отсутствует в пути к классам среды выполнения (для простоты я предполагаю, что вы используете PrimeFaces 3.x и не изменили URI taglib).
Класс ManagedBeans.LoginBean не имеет свойства doLogin.
Первое исключение, по общему признанию, несколько вводит в заблуждение, но в действительности компоненты PrimeFaces вообще не разрешаются Facelets и обрабатываются как обычный текст /html. Любое выражение EL, встроенное в разметку компонента PrimeFaces, будет затем разрешено как выражение значения. Это похоже на то, как вы пишете EL в тексте шаблона <p>#{loginBean.doLogin}</p>
, Затем он ищет getDoLogin()
метод для того, чтобы напечатать его результат.
java.lang.NoClassDefFoundError: org / primefaces / context / RequestContext
Второе исключение приближает вас к реальному объяснению проблемы: файл JAR, содержащий упомянутый класс, отсутствует в пути к классам во время выполнения веб-приложения.
Убедитесь, что файл JAR PrimeFaces присутствует в веб-приложении /WEB-INF/lib
папка развертывания.