1

Following this question the web.xml deployment file is optional since Java EE 6. I am currently using Java EE 7, Eclipse(kepler) and apache-tomcat-7.0.47 win x64. I have created a dynamic web project and a server project in Eclipse. Both projects have the deployment files(web.xml, context.xml).

After editing the web.xml in the web project and running a servlet in the context of the server a NullPointerException is thrown when trying to access any parameter defined in web.xml.

The projects have the following directory structure:

enter image description here

Should the parameters be defined in the server deployment files?

Edit #1:

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>LoginExample</display-name>
  <welcome-file-list>
    <welcome-file>login.html</welcome-file>
  </welcome-file-list>

  <context-param>
    <param-name>dbURL</param-name>
    <param-value>jdbc:mysql://localhost/mysql_db</param-value>
  </context-param>
  <context-param>
    <param-name>dbUser</param-name>
    <param-value>mysql_user</param-value>
  </context-param>
  <context-param>
    <param-name>dbUserPwd</param-name>
    <param-value>mysql_pwd</param-value>
  </context-param>
</web-app>

The parameters are accessed here:

package sebi.first;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class LoginServlet
 */
@WebServlet(
    description = "Login Servlet",
    urlPatterns = { "/LoginServlet" },
    initParams = {
            @WebInitParam(name = "user", value = "myuser"),
            @WebInitParam(name = "password", value = "mypass")
    })
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

public void init(ServletConfig config) throws ServletException {
    super.init(config);
    //we can create DB connection resource here and set it to Servlet context
    System.out.println("BEFORE OUTPUT"); // <== This is displayed in the console
    System.out.println("Check the string getServletContext().getInitParameter(\"dbURL\") = " + getServletContext().getInitParameter("dbURL")); // <== NULL pointer exception thrown
    if(getServletContext().getInitParameter("dbURL").equals("jdbc:mysql://localhost/mysql_db") &&
            getServletContext().getInitParameter("dbUser").equals("mysql_user") &&
            getServletContext().getInitParameter("dbUserPwd").equals("mysql_pwd"))
    getServletContext().setAttribute("DB_Success", "True");
    else throw new ServletException("DB Connection error");
}

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    //get request parameters for userID and password
    String user = request.getParameter("user");
    String pwd = request.getParameter("pwd");

    //get servlet config init params
    String userID = getServletConfig().getInitParameter("user");
    String password = getServletConfig().getInitParameter("password");
    //logging example
    log("User="+user+"::password="+pwd);

    if(userID.equals(user) && password.equals(pwd)){
        response.sendRedirect("LoginSuccess.jsp");
    }else{
        RequestDispatcher rd = getServletContext().getRequestDispatcher("/login.html");
        PrintWriter out= response.getWriter();
        out.println("<font color=red>Either user name or password is wrong.</font>");
        rd.include(request, response);

    }

}

Any parameter I try to access using getServletConfig().getInitParameter("paramName"); throws a NullPointerException.

Edit #2:

The stack trace thrown is as follows:

type Exception report

message Servlet.init() for servlet sebi.first.LoginServlet threw exception

description The server encountered an internal error that prevented it from fulfilling this request.

exception 

javax.servlet.ServletException: Servlet.init() for servlet sebi.first.LoginServlet threw exception
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
    org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2430)
    org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2419)
    java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    java.lang.Thread.run(Unknown Source)


root cause 

java.lang.NullPointerException
    javax.servlet.GenericServlet.getServletContext(GenericServlet.java:125)
    sebi.first.LoginServlet.init(LoginServlet.java:33)
    javax.servlet.GenericServlet.init(GenericServlet.java:160)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
    org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2430)
    org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2419)
    java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    java.lang.Thread.run(Unknown Source)

It seems that parameters defined within the annotations throw the same exception as well.

Edit #3:

I've written a short snippet suggestion:

@WebServlet(description = "Test Parameters", urlPatterns = { "/TestParam",
        "/TestParam.do" }, initParams = {
        @WebInitParam(name = "first", value = "FIRST"),
        @WebInitParam(name = "second", value = "SECOND") })
public class TestParam extends HttpServlet {
private static final long serialVersionUID = 1L;

public void init(ServletConfig config) throws ServletException {
    super.init(config);
    // we can create DB connection resource here and set it to Servlet
    // context
    System.out.println("BEFORE OUTPUT");
    System.out.println("First parameter = "
            + config.getServletContext().getInitParameter("first"));
    System.out.println("Second parameter = "
            + config.getServletContext().getInitParameter("second"));
}

protected void doPost(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {
    response.getOutputStream().println("No");
}
}

Now no exceptions are thrown, but the parameter values are both null which suggests that super(config); does not initialize the parameters in the annotations.

Edit #4:

I've managed to run the servlet and retrieve dbURL parameter value. However, now, when launched the application tries to open and gives a 404 Not Found error:

http://localhost:8080/DynamicWebProject1/servlet/sebi.first.LoginServlet

I have to manually edit the URL to:

http://localhost:8080/DynamicWebProject1/LoginServlet

in order to run the servlet.

The init() method is now:

public void init(ServletConfig config) throws ServletException {
    super.init(config);
    //we can create DB connection resource here and set it to Servlet context
    System.out.println("BEFORE OUTPUT");
    System.out.println("Check the string getServletContext().getInitParameter(\"dbURL\") = " + config.getServletContext().getInitParameter("dbURL"));

    if(config.getServletContext().getInitParameter("dbURL").equals("jdbc:mysql://localhost:3306/mysql_db") &&
            config.getServletContext().getInitParameter("dbUser").equals("mysql_user") &&
            config.getServletContext().getInitParameter("dbUserPwd").equals("mysql_pwd"))
    config.getServletContext().setAttribute("DB_Success", "True");
    else throw new ServletException("DB Connection error");
}

Still, I am not able to access parameters defined in annotations.

Community
  • 1
  • 1
Sebi
  • 4,262
  • 13
  • 60
  • 116
  • 1
    what are the parameters you are trying to access ? could you post your web.xml files ? – Dev Blanked Jan 01 '14 at 10:54
  • I am curious as to why there is also a `web.xml` file under Tomcat 7. Perhaps that is related to the problem? – Robin Green Jan 01 '14 at 11:45
  • That file is created with the project. I've tried editing both of them(from both projects), so that each has the same entries but the problem persists. – Sebi Jan 01 '14 at 11:53
  • jdbc:mysql://localhost:PORT_NO/mysql_db ,you didn't add port no. of mysql.may be it is a problem. – Rahul Sahu Jan 01 '14 at 11:56
  • I've added the port number(3306), but, the parameters are not being parsed, every parameter throws a NULL pointer exception starting from the line:System.out.println("Check the string getServletContext().getInitParameter(\"dbURL\") = " + getServletContext().getInitParameter("dbURL")); – Sebi Jan 01 '14 at 12:05
  • @Dev Regarding web.xml in Tomcat - that is master web.xml file. This is how Tomcat works. Ideally it should not be edited! – Pavel Horal Jan 01 '14 at 13:33
  • @Sebi If you face any exception, please always add stack trace. – Pavel Horal Jan 01 '14 at 13:34
  • Offtopic: That is one of the most ugly written (formatted) `if` conditions I've ever seen ;). Please learn to use curly braces... **always**! – Pavel Horal Jan 01 '14 at 14:06
  • It's a ready made example from here: http://www.journaldev.com/1877/java-servlet-tutorial-with-examples-for-beginners – Sebi Jan 01 '14 at 14:08
  • "I've written a short snippet following Marcel's suggestion" - no, you haven't. I suggested to use `config.getInitParameter(String)`. Anyhow, the values are null because the keys are not "first" & "second" but "dbURL", "dbUser" and "dbUserPwd" (unless you altered the `web.xml` in the meantime of course). – Marcel Stör Jan 01 '14 at 14:32
  • I've written that code to check if parameters are being initialized appropriately through annotations; they are not, values are still all null. I've edited the web.xml file and now I can access parameter values. However, I have to, manually, change the URL each time in order to launch the servlet. – Sebi Jan 01 '14 at 15:08
  • Is this the answer then? What is the actual question if not? – nitind Jan 03 '14 at 08:49

2 Answers2

0

If you need init params for the Servlet you should use the ServletConfig object passed to the init method (ServletConfig#getInitParameter(String)) and configure the Servlet like so:

<servlet>
    <servlet-name>MyServlet</servlet-name>
    <servlet-class>MyServlet</servlet-class>
    <init-param>
        <param-name>dbURL</param-name>
        <param-value>jdbc:mysql://localhost/mysql_db</param-value>
    </init-param>
    <init-param>
        <param-name>dbUser</param-name>
        <param-value>mysql_user</param-value>
    </init-param>
    <init-param>
        <param-name>dbUserPwd</param-name>
        <param-value>mysql_pwd</param-value>
    </init-param>
</servlet>
Marcel Stör
  • 22,695
  • 19
  • 92
  • 198
  • But I have to admit that it is not **the** answer. OP's code should work as is as well. There might be some *inconsistent deployment* issue, which is pretty common in Eclipse. – Pavel Horal Jan 01 '14 at 14:18
  • No, `GenericServlet:125` (i.e. the call to `getServletContext`) tries to [read the servlet config](http://svn.apache.org/viewvc/tomcat/tc7.0.x/tags/TOMCAT_7_0_47/java/javax/servlet/GenericServlet.java?view=markup) which is null. – Marcel Stör Jan 01 '14 at 14:27
  • `super.init(config);` ... its not ;) – Pavel Horal Jan 01 '14 at 14:27
-2

you are throwing an exception like this throws ServletException why don't you include try with catch(Exception e){e.printStackTrace();}

Rajendra arora
  • 2,186
  • 1
  • 16
  • 23