1

In my java web project I have four packages, namely com.hrms.model, com.hrms.service, com.hrms.servlet, com.hrms.utility. IN MODEL, i have the base classes project,employee and training with it's properties and geters and seters to retrieve data.

IN SERVICE i have the service implementation interface and the implementation of it is;

package com.hrms.service;

public class EmployeeServiceImplement implements IEmployeeService 
{


/** Initialize logger */
public static final Logger log = 
Logger.getLogger(EmployeeServiceImplement.class.getName());

private static Connection connection;

private static Statement statement;

private PreparedStatement preparedStatement;

/**
 * Add set of employees for as a batch from the selected employee List
 * 
 * @throws SQLException
 *             - Thrown when database access error occurs or this method is
 *             called on a closed connection
 * @throws SAXException
 *             - Encapsulate a general SAX error or warning
 * @throws IOException
 *             - Exception produced by failed or interrupted I/O operations.
 * @throws ParserConfigurationException
 *             - Indicates a serious configuration error.
 * 
 */
@Override
public void addEmployee(Employee employee) 
{

    String employeeID = EmployeeCommonUtility.generateIDs(getEmployeeIDs());

    try 
    {
        connection = EmployeeDBConnection.getDBConnection();
        /*
         * Query is available in EmployeeQuery.xml file and use
         * insert_employee key to extract value of it
         */
 preparedStatement=connection.
prepareStatement(EmployeeQueryUtility.
queryByID(EmployeeConstants.QUERY_ID_INSERT_EMPLOYEES));
        connection.setAutoCommit(false);

        //Generate employee IDs
        employee.setEmployeeID(employeeID);
        preparedStatement.setString(EmployeeConstants.
COLUMN_INDEX_ONE, employee.getEmployeeID());
        preparedStatement.setString(EmployeeConstants.
COLUMN_INDEX_TWO, employee.getNIC());
            // Add employee
        preparedStatement.execute();
        connection.commit();

    } 
} 

    catch (SQLException | SAXException | IOException | ParserConfigurationException | ClassNotFoundException e) 
    {
        log.log(Level.SEVERE, e.getMessage());
    } 

    finally 
    {
        /*
         * Close prepared statement and database connectivity at the end of
         * transaction
         */
        try 
        {
            if (preparedStatement != null) 
            {
                preparedStatement.close();
            }

            if (connection != null) 
            {
                connection.close();
            }
        } 

        catch (SQLException e) 
        {
            log.log(Level.SEVERE, e.getMessage());
        }
    }
} 
//from this part onwards i have replased employees with project, since it's 
project section which causes the error.
@Override
public Project getProjectByID(String projectID) 
{
    return actionOnProject(projectID).get(0);
}
@Override
public ArrayList<Project> getProjects() 
{
    return actionOnProject(null);
}
private ArrayList<Project> actionOnProject(String projectID) 
{
    ArrayList<Project> projectList = new ArrayList<Project>();

    try 
    {
        connection = ProjectDBConnection.getDBConnection();
        /*
         * Before fetching project it checks whether project ID is
         * available
         */
        if (projectID != null && !projectID.isEmpty()) 
        {
            /*
             * Get project by ID query will be retrieved from
             * ProjectQuery.xml
             */
            preparedStatement = connection.prepareStatement
(ProjectQueryUtility.queryByID(ProjectConstants.QUERY_ID_GET_PROJECT));
            preparedStatement.setString
(ProjectConstants.COLUMN_INDEX_ONE, projectID);
        }
        /*
         * If project ID is not provided for get employee option it display
         * all projects
         */
        else 
        {
            preparedStatement = connection.prepareStatement
(ProjectQueryUtility.queryByID(ProjectConstants.QUERY_ID_ALL_PROJECTS));
        }

        ResultSet resultSet = preparedStatement.executeQuery();

        while (resultSet.next()) 
        {
            Project project = new Project();

    project.setProjectID
(resultSet.getString(ProjectConstants.COLUMN_INDEX_ONE));

 project.setName
(resultSet.getString(ProjectConstants.COLUMN_INDEX_TWO));

    project.setStartDate
(resultSet.getString
(ProjectConstants.COLUMN_INDEX_THREE));

  project.setEndDate
(resultSet.getString(ProjectConstants.COLUMN_INDEX_FOUR));

  project.setDepartment(resultSet.getString
(ProjectConstants.COLUMN_INDEX_FIVE));
            project.setCost(Double.parseDouble
(resultSet.getString(ProjectConstants.COLUMN_INDEX_SIX)));

  project.setClientID
(resultSet.getString
(ProjectConstants.COLUMN_INDEX_SEVEN));

            projectList.add(project);
        }

    } 

    catch (SQLException | SAXException | 
IOException | ParserConfigurationException | ClassNotFoundException e) 
    {
        log.log(Level.SEVERE, e.getMessage());
    } 

    finally 
    {
        /*
         * Close prepared statement and database connectivity at the end of
         * transaction
         */
        try 
        {
            if (preparedStatement != null) 
            {
                preparedStatement.close();
            }

            if (connection != null)
            {
                connection.close();
            }
        } 

        catch (SQLException e) 
        {
            log.log(Level.SEVERE, e.getMessage());
        }
    }

    return projectList;
}

likewise i have methods in here for updating, deleting and listing employees in the database.

In Servlet I have different servlets to Add, Delete, Update and Get Employees.

 **In Utility** I have these classes;

public class EmployeeCommonUtility 
{

/** Initialize logger */
public static final Logger log = Logger.getLogger(IEmployeeService.class.getName());

public static final Properties properties = new Properties();

static {
    try {

        // Read the property only once when load the class
        properties.load(EmployeeQueryUtility.class.getResourceAsStream(EmployeeConstants.PROPERTY_FILE));

    } 

    catch (IOException e) 
    {
        log.log(Level.SEVERE, e.getMessage());
    }
}

/**
 * Add new Employee ID
 * 
 * @param arrayList
 * @return
 */
public static String generateIDs(ArrayList<String> arrayList) 
{

    String id;
    int next = arrayList.size();
    next++;
    id = EmployeeConstants.EMPLOYEE_ID_PREFIX + next;
    if (arrayList.contains(id)) 
    {
        next++;
        id = EmployeeConstants.EMPLOYEE_ID_PREFIX + next;
    }

    return id;
}
}


public class EmployeeConstants 
{

/** Constant for config.properties key for query file path */
public static final String QUERY_XML = "queryFilePath";

/** Constant for file path of config.properties */
public static final String PROPERTY_FILE = "employee.config.properties";
.
.
.
.
}

This class contains all the constants in the project. employee.config.properties contains the username, password and the relevant .xml query file name to retrieve data.

public class EmployeeQueryUtility extends EmployeeCommonUtility 
{

/**
 * This method read the EmployeeQuery.xml file and retrieve the query by
 * query id.
 * 
 * @param id
 *            QueryID to retrieve elements
 * 
 * @return String formatted query will be returned as output
 * 
 * @throws ParserConfigurationException
 *             - Indicates a serious configuration error.
 * @throws IOException
 *             - This class is the general class of exceptions produced by
 *             failed or interrupted I/O operations.
 * @throws SAXException
 *             - Encapsulate a general SAX error or warning.
 * 
 * @see EmployeeServiceImplement#addEmployees()
 * @see EmployeeServiceImplement#createEmployeeTable()
 * @see EmployeeServiceImplement#displayAllEmployees()
 * @see EmployeeServiceImplement#removeEmployee(String)
 * 
 */
public static String queryByID(String id) throws SAXException, IOException, ParserConfigurationException 
{
    NodeList nodeList;
    Element element = null;
    /*
     * Read the EmployeeQuery.xml file and read each query node into node
     * list. It refers tag name query
     */
    nodeList = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File(System.getProperty("catalina.base") + "\\wtpwebapps\\HRMS\\WEB-INF\\EmployeeQuery.xml"))
            .getElementsByTagName(EmployeeConstants.TAG_NAME);

    /*
     * Extract the node from node list using query id query id is taken from
     * query node attribute
     */

    for (int value = 0; value < nodeList.getLength(); value++) 
    {
        element = (Element) nodeList.item(value);
        if (element.getAttribute(EmployeeConstants.ATTRIB_ID).equals(id))
            break;
    }

    return element.getTextContent().trim();
}
}

package com.hrms.utility;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

/**
 * This is the Database connection creation class .
 * @see #CommonUtility
 */

public class EmployeeDBConnection extends EmployeeCommonUtility 
{

private static Connection connection;

// This works according to singleton pattern
private EmployeeDBConnection() 
{
}

/**
 * Create Database connection for the given URL, Username and Password
 * 
 * @return Connection this returns SQL connection for MySql Database
 * 
 * @throws ClassNotFoundException
 *             - Thrown when an application tries to load in a class through
 *             its string name
 * @throws SQLException
 *             - An exception that provides information on a database access
 *             error or other errors
 */
public static Connection getDBConnection() throws ClassNotFoundException, SQLException 
{
    /*
     * This create new connection objects when connection is closed or it is
     * null
     */
    if (connection == null || connection.isClosed())
    {


    Class.forName(properties.getProperty(EmployeeConstants.DRIVER_NAME));
        connection = DriverManager.getConnection(properties.getProperty(EmployeeConstants.URL),
                properties.getProperty(EmployeeConstants.USERNAME), properties.getProperty(EmployeeConstants.PASSWORD));
    }

    return connection;
}
}

In GetEmployee.jsp

<%@page import="com.hrms.model.Employee"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<jsp:include page="/WEB-INF/views/header.jsp"></jsp:include>
<h2 class="h2" >Get Employee</h2>
<br>
<br>
<%
    Employee employee = (Employee) request.getAttribute("employee");
%>

<form method="POST" action="UpdateEmployeeServlet">
    <table>
        <tr>
            <td>Employee ID</td>
            <td><input type="text" name="employeeID" disabled="disabled"
                value="<%=employee.getEmployeeID()%>" /></td>
        </tr>
        <tr>
            <td>NIC</td>
            <td><input type="text" name="NIC" 
                value="<%=employee.getNIC()%>" /></td>
        </tr>
        <tr>
            <td>Employee Name</td>
            <td><input type="text" name="employeeName"
                value="<%=employee.getName()%>" /></td>
        </tr>

        <tr>
            <td colspan="2">
                <input type="hidden" name="employeeID" value=" 
 <%=employee.getEmployeeID()%>" /> 
                <input type="submit" value="Update Employee" class="btn btn- 
 primary"/>
            </td>
        </tr>
    </table>
</form>

<table>
    <tr>
        <td colspan="2">
            <form method="POST" action="DeleteEmployeeServlet">
                <input type="hidden" name="employeeID" value="<%=employee.getEmployeeID()%>" /> 
                <input type="submit" value="Delete  Employee" class="btn btn-primary"/>
            </form>
        </td>
    </tr>
</table>
<jsp:include page="/WEB-INF/views/footer.jsp"></jsp:include>
</body>
</html>

In ListEmployee.jsp

 <%@page import="com.hrms.model.Project"%>
 <%@page import="java.util.ArrayList"%>
 <%@page import="com.hrms.service.ProjectServiceImplement"%>
 <%@page import="com.hrms.service.IProjectService"%>

 <html>
 <head>
 <!-- Bootstrap -->
 <link href="css/bootstrap.min.css" rel="stylesheet">

 </head>
 <body>
 <jsp:include page="/WEB-INF/views/header.jsp"></jsp:include>
 <br>
 <br>
 <form method="POST" action="addProject.jsp">
    <td scope="row"><input type="submit" value= "Add Project" 
 class="btn btn-primary btn-md" />  
 </form>
  <div align="left">
    <table class="table table-hover">
     <caption><h2 style="color:#800080" class="text-center">
 HumanConcepts inc. Project Database</h2></caption>
      <thead>
      <tr>
            <th scope="col">Project ID</th>
            <th scope="col">Project Name</th>
            <th scope="col">Start Date</th>
            <th scope="col">End Date</th>
            <th scope="col">Department</th>
            <th scope="col">Cost</th>
            <th scope="col">Client ID</th>
        </tr>
        <thead>
        <%
            IProjectService iProjectService = new ProjectServiceImplement();
                        ArrayList<Project> 
 arrayList = iProjectService.getProjects();

                        for(Project project : arrayList){
        %>
        <tbody>
         <tr>
            <td scope="row"> <%=project.getProjectID() %> </td>
            <td scope="row"> <%=project.getName() %> </td>
            <td scope="row"> <%=project.getStartDate() %> </td>
            <td scope="row"> <%=project.getEndDate() %> </td>
            <td scope="row"> <%=project.getDepartment() %> </td>
            <td scope="row"> <%=project.getCost() %> </td>
            <td scope="row"> <%=project.getClientID() %> </td>
            <form method="POST" action="GetProjectServlet">
            <td scope="row">
            <input type="submit" value= "Select Project" 
 class="btn btn-primary btn-xs" />  
            <input type="hidden" name="projectID" 
value="<%=project.getProjectID()%>"/>
             </form>
             </td>  
            </tr>
        <tbody>         
        <%  
           }
        %>     
    </table>
    </div>
    <jsp:include page="/WEB-INF/views/footer.jsp"></jsp:include>
</body>
</html>

for each employee,project and training, i have the same format of code segments.

In index.jsp i have 4 button clicks to access them. In each of them i'm redirecting them to their relevant servlet. Basically I'm trying to implement a simple administrator panel.

This employee class is functioning accurately, but when it's come to remaining two classses, they throw an excepton,

HTTP Status 500 – Internal Server Error Message An exception occurred processing [WEB-INF/views/ListProjects.jsp] at line [56]

Description The server encountered an unexpected condition that prevented it from fulfilling the request.

Exception

org.apache.jasper.JasperException: An exception occurred processing [WEB-INF/views/ListProjects.jsp] at line [56] 53: 54: <% 55: IProjectService iProjectService = new ProjectServiceImplement(); 56: ArrayList arrayList = iProjectService.getProjects(); 57:
58: for(Project project : arrayList){ 59: %>

Since it's really hard to put all the code segments in here, if you need to clarify any place in my code, feel free to ask me to put it. I think, when establishing two new connections in the same database twice, causes this error. But I don't know how to navigate through different tables by preserving MVC.

Any suggestions to overcome this error? Thank You!

Full Stack Trace

May 17, 2018 9:00:32 PM org.apache.catalina.core.StandardWrapperValve invoke SEVERE: Servlet.service() for servlet [ListProjectServlet] in context with path [/HRMS] threw exception [An exception occurred processing [WEB-INF/views/ListProjects.jsp] at line [56]

53: 54: <% 55: IProjectService iProjectService = new ProjectServiceImplement(); 56: ArrayList arrayList = iProjectService.getProjects(); 57:
58: for(Project project : arrayList){ 59: %>

Stacktrace:] with root cause java.lang.NoClassDefFoundError: Could not initialize class com.hrms.utility.ProjectDBConnection at com.hrms.service.ProjectServiceImplement.actionOnProject(ProjectServiceImplement.java:242) at com.hrms.service.ProjectServiceImplement.getProjects(ProjectServiceImplement.java:137) at org.apache.jsp.WEB_002dINF.views.ListProjects_jsp._jspService(ListProjects_jsp.java:186) at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:444) at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:386) at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:330) at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:712) at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:459) at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:384) at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:312) at com.hrms.servlet.ListProjectServlet.doPost(ListProjectServlet.java:47) at javax.servlet.http.HttpServlet.service(HttpServlet.java:660) at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:494) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:651) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:407) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:754) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1376) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Unknown Source)

Hashini
  • 89
  • 1
  • 11
  • What you want to check is ListProjects.jsp] at line [56]. See if you can find a problem there. You shouls also have a java stack trace where it gives a description of the exception. Try to follow the stack trace to identify the first class in the chain that is from your domain, most likely the problem pops up there. – Juan May 17 '18 at 03:17
  • @Juan but thar line 56 doesn’t indicate any errors. As the employee version of that page is perfectly working, I have copy pasted the same into project version as well. And also it’s not indicating any errors. That’s why I’m confused:/ – Hashini May 17 '18 at 03:20
  • You should turn off auto commit before getting your preparedstatement from the connection. And don’t ever save database connections or other jdbc objects in static fields. – Nathan Hughes May 17 '18 at 03:22
  • @NathanHughes would you please explain what’s happening with that suggestion? – Hashini May 17 '18 at 03:23
  • Your concurrent service calls are overwriting the static jdbc fields. Big problem. Store jdbc objects as local variables of the method. – Nathan Hughes May 17 '18 at 03:24
  • ArrayList arrayList = iProjectService.getProjects(); Where is this method? iProjectService.getProjects(); I couldn't locate it in the code you posted. – Juan May 17 '18 at 03:28
  • By the way see if you find a different exception down the stack trace chain. Look where it says Caused By ... – Juan May 17 '18 at 03:35
  • @hashini.W, seems like there is a chained exception for the 500 that you get, would you mind posting the full error. – Juliyanage Silva May 17 '18 at 03:58
  • @NathanHughes would you tell me how could I turn off auto commit? will it affect my other tables? – Hashini May 17 '18 at 15:45
  • @Juan I have added the ListProject.jsp which contains the line number 56, along with the implementaion of inerface iProjectService. It's there in the service section. as the employee version is working well, i have replaced the employee with the project in the later part of the code. Do you need anything more? – Hashini May 17 '18 at 16:00
  • @ShamithaSilva i have added the stack trace. would you please check it and figure out the error? :/ – Hashini May 17 '18 at 16:01
  • @hashini.W, Juan saved you I guess.. – Juliyanage Silva May 18 '18 at 03:31

2 Answers2

1

The problem seems to be that the class com.hrms.utility.ProjectDBConnection is not found on the class path (root cause java.lang.NoClassDefFoundError).

This class is being used when calling iProjectService.getProjects() called on line 56 of the jsp file.

This method is calling actionOnProject(null), which in turn calls connection = ProjectDBConnection.getDBConnection();

Check if this class exists, because for the Employee it has a different name.

If it exists make sure it is found on the runtime class path.

Juan
  • 5,525
  • 2
  • 15
  • 26
1

Ok you have multiple issues here.

Conceptually the way MVC works in a Java web application is that there's a controller that calls backend services and handles putting together the view. That's why they call it the controller, it is in charge of putting everything together.

A request gets handled like this:

1) an HTTP request comes in and gets assigned a thread by the servlet container,

2) a dispatching servlet decides which controller handles the request and calls the right controller method with the request information, then

3) the controller calls backend services to do the needful for the request, then either puts stuff the view needs into the request attributes and forwards to a view (if this is a HTTP GET), or redirects to another url (if the current action is a POST) with a GET request which goes through steps 1-3 , and then

4) a view handler uses the view and request attributes info to render a response (the jsp in your case)

You're not doing that, you have your jsp calling backend services, which is not MVC. This application is making an HTTP POST and it goes to the JSP and calls backend services from there.

Also you have your jdbc objects, including your database connection, stored in static fields, static fields are available to all the requests so that concurrent requests will overwrite fields in use by other requests or use objects allocated for other requests. Using static fields makes this effectively a single-user web application. JDBC objects should be kept in local variables so that concurrent requests won't interfere with each other. Web applications need to use a connection pool where for each transaction a connection is acquired from the pool, then closed when the operation is completed (which returns it to the pool).

Then there's the posted stacktrace, it shows some utility you're using to create a database connection that isn't found on the classpath or which ran into problems, for instance see https://stackoverflow.com/a/28507116: if some error occurs while the class is loading then you can get this error.

Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276