好吧,伙计们。 经过3个小时的奋斗之后,我决定在这里发布问题,因为我无法解决这个问题。JSF&Primefaces NoClassDefFoundError
让我们来谈谈。
我已经用PrimeFaces 3完成了一个NetBeans web项目。 它工作正常,没有任何问题。
但我需要制作一个企业应用程序,使用该Web项目作为Web模块。
我已经有了一个EJB项目几乎完成的EE项目,所以我开始通过将Web页面复制到Enterprise项目的War部分并重写Managed Beans来“合并”这两个项目。
但事情变得混乱,所以我不得不做出一些改变。
我会写的2个文件在不同的版本(记住,这个代码在单个Web项目工程!)代码:
- JSF页面 -
[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]
- - 托管bean -
[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]
即使这个代码在我的Web项目中,“移动”,它充分EE应用程序使我的错误:
The class 'ManagedBeans.LoginBean' does not have the property 'doLogin'.
因此,假设问题是由doLogin的签名引起的(它需要一个参数,但是在没有它的情况下调用JSF页面),并且尽管这是组件在PrimeFaces文档中使用的方式,我只是把它改为:
- JSF页面 -
[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]
- 托管bean -
[cut]
public void doLogin() {
user = loginUser.doLogin(username, password);
loggedIn = false;
FacesMessage msg;
RequestContext context = RequestContext.getCurrentInstance();
[cut]
所以我已经改变了方法签名和commandButton的动作。
通过这种变化,似乎先前的错误gone..but ..
java.lang.NoClassDefFoundError: org/primefaces/context/RequestContext
是的,现在我已经得到了这一个。
只是为了弄清楚事情,图书馆是进口的,一切都很好。 NetBeans可以从org.primefaces。*中正确导入,所以我假设jar文件被加载。
但是,这里出现了奇怪的事情。
从库中删除PrimeFaces并导入一个新的jar(与以前一样,它只是在一个不同的目录中),它似乎工作。
页面加载没有问题。
但是这种情况持续到下一次部署,因为新的部署将导致我像以前一样导致NoDefClassFoundError。
这是一个非常随机的事情,因为它在玩过库路径后得到解决,但它们都不适用于多个部署。
我不知道该怎么做,因为事情很奇怪。
有时它只是加载黄色警告的页面,说他无法找到http://primefaces.org/ui名称空间(或类似的东西)的库。
对于问题的长度,我很抱歉,但很难解释我所看到的。
有没有人能指出我的解决方案?
你当然是对的,因为它现在可以工作了,但为什么第一个web项目没有WEB-INF/lib目录而工作呢? – StepTNT 2012-03-23 20:35:38
我不使用Netbeans,但不应该查看项目中的文件夹,也许Netbeans隐藏或更改它,但应该查看部署中的文件夹。这就是运行时所需要的。导出到WAR/EAR并看看你自己。 – BalusC 2012-03-23 20:39:12