NoSuchMethodError - 在运行Web项目时

时间:2014-03-26 10:21:41

标签: java intellij-idea nosuchmethoderror

我尝试在Intellij 13.1上运行简单的web项目并得到下一个错误:

SEVERE: Servlet.service() for servlet [com.java.task11.webapp.LoginServlet] in context with path [] threw exception [Servlet execution threw an exception] with root cause
java.lang.NoSuchMethodError: com.java.task11.controller.dao.factory.DAOFactory.getUserDAO()Lcom/java/task11/controller/dao/factory/UserDAO;
    at com.java.task11.controller.service.UserService.getByEmail(UserService.java:39)
    at com.java.task11.webapp.LoginServlet.doPost(LoginServlet.java:41)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

来自java API

Thrown if an application tries to call a specified method of a class (either static or instance), and that class no longer has a definition of that method.

Normally, this error is caught by the compiler; this error can only occur at run time if the definition of a class has incompatibly changed.

LoginServlet上的41 line

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    request.setCharacterEncoding("UTF-8");

    HttpSession session = request.getSession();
    String email = request.getParameter("email");
    String password = MD5Utils.getMD5String(request.getParameter("password"));
    User user = null;
    try {
        user = new UserService().getByEmail(email);        // 41 line
    } catch (DAOException e) {
        log.error(e);
    }

39 line UserService

public User getByEmail(String email) throws DAOException {
    if (DAOFactory.getInstance().getUserDAO().getByEmail(email).isEmpty()) {   // 39 line
        return null;
    } else {
        return DAOFactory.getInstance().getUserDAO().getByEmail(email).get(0);
    }
}

从堆栈跟踪L表示引用的问题 - 类的实例。

但一切都应该奏效。

以下是 DAOFactory 的摘录:

public abstract class DAOFactory {
    private static DAOFactory instance;

    public static DAOFactory getInstance() throws DAOException {
        try {
            if (null == instance) {
                instance = (DAOFactory) Class
                        .forName("com.java.task11.controller.dao.implement.JDBCDAOFactory")
                        .newInstance();
            }
        } catch (Exception e) {
            throw new DAOException("Could not create the DAOFactory instance", e);
        }

        return instance;
    }

    public abstract UserDAO getUserDAO();

更新

我已经实现了这个界面:

public class UserDAOImpl implements UserDAO {
   // other methods
    public List<User> getByEmail(String email) throws DAOException {
    PreparedStatement ps = null;
    ResultSet rs = null;
    List<User> ret = new ArrayList<User>();

    try {
        if (null == email) {
            ps = getConn().prepareStatement(
                    DBUtil.selectNull(tableName, allColumns,
                            Arrays.asList("email")));
        } else {
            ps = getConn().prepareStatement(
                    DBUtil.select(tableName, allColumns,
                            Arrays.asList("email")));
            DBUtil.bind(ps, 1, email);
        }

        rs = ps.executeQuery();

        while (rs.next())
            ret.add(fromResultSet(rs));
    } catch (SQLException e) {
        throw new DAOException(e);
    } finally {
        DBUtil.close(ps, rs);
    }

    return ret;
}

这个逻辑的最后一个难题是JDDCFactory类:

public class JDBCDAOFactory extends DAOFactory {

    public UserDAO getUserDAO() {
        return new UserDAOImpl();
    }

所有必要的罐子都添加到类路径中。甚至更多这个代码工作,这发生在我从远程仓库撤出后。但是在其他人身上一切正常。

如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

修改:将getEmail()添加到您的界面。

public User getByEmail(String email) throws DAOException {
    if (DAOFactory.getUserDAO().getByEmail(email).isEmpty()) {   // 39 line
        return null;
    }
}

由于您的getUserDAO()正在返回UserDAO(您的接口),因此您会抛出MethodNotFoundException,因为您的接口未实现该方法。您现在应该将其添加到您的方法中,或者重新考虑getUserDAO()返回的内容。

答案 1 :(得分:0)

您必须实施getUserDAO()方法。

尝试在此处删除getInstance

public User getByEmail(String email) throws DAOException {
    if (DAOFactory.getUserDAO().getByEmail(email).isEmpty()) {   // 39 line
        return null;
    } else {
        return DAOFactory.getUserDAO().getByEmail(email).get(0);
    }
}

DAOFactory实施getUserDAO()内容如下:

public UserDAO getUserDAO() {
    return getInstance().getUserDAO();
}