2012-03-22 117 views
1

好吧,伙计们。 经过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名称空间(或类似的东西)的库。

对于问题的长度,我很抱歉,但很难解释我所看到的。

有没有人能指出我的解决方案?

回答

6

这两个问题都有完全相同的原因:PrimeFaces JAR文件不在运行时类路径中(为了简单起见,我假设您使用PrimeFaces 3.x并且没有更改taglib URI)。

The class 'ManagedBeans.LoginBean' does not have the property 'doLogin'.

第一个例外是不可否认有点误导,但在现实中PrimeFaces组件没有被Facelets的根本解决,作为纯文本/ HTML处理。 任何 PrimeFaces组件标记中内联的EL表达式将被解析为值表达式。这就像你在模板文本中写EL平原一样,如<p>#{loginBean.doLogin}</p>。然后查找getDoLogin()方法以打印其结果。

java.lang.NoClassDefFoundError: org/primefaces/context/RequestContext

第二个例外带给你更接近问题的真正解释:包含提到类的JAR文件不在web应用程序的运行时类路径。

确保PrimeFaces JAR文件存在于部署的webapp的/WEB-INF/lib文件夹中。

+0

你当然是对的,因为它现在可以工作了,但为什么第一个web项目没有WEB-INF/lib目录而工作呢? – StepTNT 2012-03-23 20:35:38

+1

我不使用Netbeans,但不应该查看项目中的文件夹,也许Netbeans隐藏或更改它,但应该查看部署中的文件夹。这就是运行时所需要的。导出到WAR/EAR并看看你自己。 – BalusC 2012-03-23 20:39:12