My problem is that I have to set a variable in a try statement otherwise I get a compile error.
Later on I need to use that variable but it is now out of scope, or so I believe. I initialise the variable outside the try statement and set it to null, I thought that it might then be accessible outside, but I still get a NullPointerException
.
The code is below, with lots of it taken out to make reading easier - I know it's bad code, but I am new to Servlets and just wanted to see it running with all the moving parts doing what they are supposed to.
I have created another class that calls createDocs(...) and passes in the required parameters, and it works fine. So that is making me curious as to why when I call rs.getString("name")
I get the NullPointerException
, as this is exactly what I do from the other class (run from a main method for convenience) and it works as expected.
The variable in question is the ResultSet variable "rs" -
public class AgReportServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public AgReportServlet() {
super();
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ResultSet rs = null;
try {
rs = docs.getDocs(con, start, end, zone, locality);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
response.setContentType("text/xml");
PrintWriter out = response.getWriter();
out.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" +
out.println(
"<table border=\"0\" cellspacing=\"0\" cellpadding=\"6\">\n");
// I have a resultset object need to iterate through it to display the file names
try {
while (rs.next()) { // page through the result set
out.println(
" <tr>\n" +
" <td>: " + rs.getString("name") + "</td>\n" +
" </tr>\n"
);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
out.println(
"</table></body>\n" +
"</html>"
);
out.flush();
out.close();
}
}
Thanks everyone for your help. First you helped me identify that there had to be some kind of exception being thrown. When I looked at the Tomcat console I could see it was a class not fund error for the MySQL connector. I had included that in my project, but not within the project itself - I just lazily referred to it in my lib directory, so ultimately the exception caused the problem, but using your suggestions such as if(rs != null) helped me get to the root cause.
Initially I thought it had something to do with the variable being out of scope. Clearly that was not it.
Your problem is that if this statement:
throws an exception then the value of rs is still
null
. So what I would do is move the loop inside the same try-catch block. Alternatively you can check whether it's still null before trying to use it.Setting the value to null outside the try-catch block isn't bad code though. That's just what you have to do if you want the rs variable outside the try block (and that includes inside one of the catch clauses). Your rs while loop should probably just be within the same try block.
Why don't you simply add a
before
This should help (as far as I understand it)
The way you are declaring the rs variable and the first try/catch block are ok.
Its just that after the first try/catch you need to remember that rs will still be null if there was an error in the first try/catch. So just make sure you test rs for null before you try to access it.