A sever issue I am facing after deployment on Glassfish4 and Ubuntu 14.04 . In java, I am not using hibernate due to some reasons. I am manually getting the resultset as a result of query, sending the result set to JSP page and iterating over it.
Problem is, I have set the finally block as below:
finally {
try {
if (conn != null) {
conn.close();
}
if (ctx != null) {
ctx.close();
}
if (cstatement != null) {
cstatement.closeOnCompletion();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NamingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
And because I am sending the Resultset to JSP page through session, I am closing the result on JSP page as follows:
if(resultset!=null) resultset.close();
Now, problem is, after few minutes my application starts giving exception that max of the connection pools has been used.
What should I do to avoid exception?
The problem with your current finally block is:
If any exception is thrown from one of the close command, the following command will not be run. Since the issue seems to be resource leak so that might be the cause.
If you are running under JDK7+ and the resource is auto-closable, try to use
try(Connection conn=DriverManager.getConnection();
Statement stat=conn.createStatement){
}
Then the resources will be closed safely exiting try block.
And if you need to close resource from finally block, try to wrap a try catch for each close statement.
For ordering of closing resource, always close the resource you created later first.
Related
Here is my doPost method of my servlet that in theory add data in db
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
Date d=(Date) request.getAttribute("data");
DatiAnagrificiImpl dai=new DatiAnagrificiImpl();
dai.addDatiAnagrafici(new DatiAnagraficiBean(request.getParameter("username"),request.getParameter("cap"),request.getParameter("nome")
,request.getParameter("cognome"),request.getParameter("telefono"),d));
}
And here the method that will insert data in db
enter public void addDatiAnagrafici(DatiAnagraficiBean dab) {
// TODO Auto-generated method stub
try {
Statement s=c.createStatement();
s.executeUpdate("insert into Dati_anagrafici values('"+dab.getIdUtente()+"','"+dab.getIdCittà()+"',"
+ "'"+dab.getNome()+"','"+dab.getCognome()+"','"+dab.getTelefono()+"','"+dab.getDataNascita()+"')");
}catch(SQLException e) {
}finally {
al.add(dab);
}
}
But when I try to do that with a servlet I have this error
ERROR 1205 (HY000): Lock wait timeout exceeded;
Someone knows how to resolve? If I do the same thing with a normal java class is all fine.
It appears you have a transaction that's not completing. In MySQL, try running these to get a view into what's going on:
SHOW ENGINE INNODB STATUS;
SHOW FULL PROCESSLIST;
One or both should provide some clues.
A few issues stand out in your code. The first thing I would address is that the Statement is never closed (but should be). You can close the statement in a few places, but as the simplest example, you could close it right after you call executeUpdate(), like this:
Statement s = c.createStatement();
s.executeUpdate("...");
s.close();
Another easy change: when catching an exception, do something with it (instead of "swallowing" the exception silently). It's possible there's an exception being thrown, but the code above will hide that exception. For example, instead of this:
catch (SQLException e) {
}
try this:
catch (SQLException e) {
e.printStackTrace();
}
A final improvement would be to rework the code a bit to use "try-with-resources" - a nice convenience to automatically close a resource for you (in this case, your Statement). That could look like this:
Connection connection = getConnection();
try (Statement statement = connection.createStatement()) {
statement.executeUpdate("...");
} catch (SQLException e) {
e.printStackTrace();
}
EDIT: One more thing.. the connection can (and should) be committed by calling commit() (or rollback() if something went wrong). Here's a final edit to try which shows commit() in the main try block, and a rollback() in the catch block to undo the transaction if an exception is thrown:
Connection connection = getConnection();
try (Statement statement = connection.createStatement()) {
statement.executeUpdate("...");
connection.commit();
} catch (SQLException e) {
e.printStackTrace();
try {
connection.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
}
I have in my code the next:
try (DockerClient client = DefaultDockerClient.fromEnv().connectTimeoutMillis(TimeUnit.SECONDS.toMillis(3)).build()) {
//some code here
}catch (DockerCertificateException e) {
log.warn("Failed to connect Docker Client {}", e.getMessage());
}
finally {
}
I need to close the client in the final block, but I can't because I'm getting an error (Cannot resolve symbol client).
Is there any way to close this client in the final block?
Client will be closed, cause you are using try-with-resources (when you open resourse in try(resource definition)), which closes resource after try block automatically, you don`t need to write finally block.
The object in try(...) must implement AutoClosable and that object will be automatically closed whether or not an exception happens. You don't need the finally block at all.
If the object does not implement AutoClosable, you can fall back to the old try-catch-finally block as
DockerClient client = null;
try {
//some code here
client = DefaultDockerClient.fromEnv().connectTimeoutMillis(TimeUnit.SECONDS.toMillis(3)).build();
} catch (DockerCertificateException e) {
log.warn("Failed to connect Docker Client {}", e.getMessage());
} finally {
if (client != null) client.close();
}
This is called the Java try-with-resources block. You can see an example that compares normal try-catch-finally block with the try-with-resources block here: https://www.baeldung.com/java-try-with-resources#replacing
Is it fine to have a nested try block without a catch or finally block and let the outer catch block handle the exception if any from the nested try block?
Something like:
try (Connection con = ds.getConnection();
PreparedStatement ps = con.prepareStatement(sql);) {
//nested try block without a catch or finally block
try (ResultSet rs = ps.executeQuery();) {
while (rs.next()) {
list.add(rs.getInt("id"));
}
}
} catch (SQLException e) {
e.printStackTrace();
}
If you remove the 'try' the result set will not close automatically.
The try-with-resources statement sort of executes rs.close in a hidden finally.
It is good practice to close the resultset, open resultset can lead to problems : java.sql.SQLException: - ORA-01000: maximum open cursors exceeded
Problem with exception catching in this example is how do you differentiate between datasource exceptions, query creation exceptions or query execution SQLExceptions? I would probably throw a specific RuntimeException when my datasource can not deliver an connection.
No. Your code won't compile.
Every try block (even nested) must be followed with catch(..) and/or finally.
In your case add a second catch block if you want to handle any other additional exceptions.
Sample code:
try {
// code which may throw exceptions
} catch(Exception e1) {
// e1 specific code
} catch (Exception e2) {
// e2 specific code
} finally {
// Optional. Executes whether exception thrown or not!
}
There are many similar questions but I am closing the connection in the finally block. I am testing so I am refreshing the same page often.
in the DAO ( which is called from the controller when the view is accessed)
try {
con= DB.getConnection();
st= connection.createStatement();
rs = statement.executeQuery(MY_QUERY);
while (rs.next()) {
...
}
} catch (SQLException e ) {
e.printStackTrace();
} finally {
try { rs.close(); } catch (Exception e) { /* ignored */ }
try { st.close(); } catch (Exception e) { /* ignored */ }
try { conn.close(); } catch (Exception e) { /* ignored */ }
}
in application.conf
db.default.driver=org.postgresql.Driver
db.default.url="jdbc:postgresql://hostname2/schema"
db.default.user="myuser"
db.default.password="mypass"
Inevitably after a few hours coding I hit the no more connections error. shouldn't the finally close the connection and return it to myuser's pool? Does hitting CTRL-D not close the connection?
Using: PostgreSQL, Java with Play2 framework, running with play run (testing/building stage)
UPDATE: still looking for a reason
Here's some working database code from a project I'm working on:
try
{
//Run a query.
statement = connection.createStatement();
statement.execute(db_request);
results = statement.getResultSet();
//Put the list of names into the table.
table = getTableResults(results);
if(table == null)
return null;
System.out.println("Running database command: " + db_request);
//End.
results.close();
statement.close();
connection.close();
}
catch (SQLException ex)
{
System.out.println("SQLException: " + ex.getMessage());
System.out.println("SQLState: " + ex.getSQLState());
System.out.println("VendorError: " + ex.getErrorCode());
return null;
}
return table;
I run all the close statements at the end of the try block and only catch SQLException. If anything else is going on, the console prints the stack trace and shows me the exact line where it broke.
By the way, catch(Exception e) is a REALLY bad coding practice that causes Java to hide errors from you unless they're fatal. I imagine you'd get a lot more information from the stack trace that's automatically printed to the console if you removed those lines.
Seeing how Play Framework gives you play.Logger class, you could instrument that finally and the try {} catch {} inside it with
Logger.info("Something happened...");
and start getting the idea of whats happening for yourself. From top of my head - nothing looks wrong with your code. Do you know the max number of concurrent connections that your db supports btw? If its running in the cloud, there may be an artificial limitation as well.
I have a method that looks like this:
try {
doStuff();
} catch (Exception ex) {
logger.error(ex);
}
(I don't really use method names like doStuff - this is just to make things easy)
In doStuff I do a variety of things, among them is call a data access method (so, another method within doStuff) that ends with the following:
} catch (SQLException ex) {
logger.error(ex);
} finally {
try {
connection.close();
proc.close();
results.close();
} catch (Exception e) {
logger.error(e);
} //<--Exception thrown here. HUH?
}
return stuff;
When stepping through this code I get to the second to last curly brace (marked with a comment) and then jump up to the catch in the first code block with a NullPointer exception. The results.close() is what is being run right before it (results is not null). My IDE (NetBeans) doesn't provide a stack trace (it shows the stack trace is null) or any other information other than the name of the exception (from what I can tell).
This code was running fine previously. In fact while it was running, I changed the stored procedure that the data access method (where I'm getting this exception) was calling, and then this error started to occur (without the application having been stopped at all). I've since tried rebuilding and restarting but to no avail. I could change the sproc back but I really want to find out what this error is from since it makes no sense that the sproc would even be a part of this considering where in the code the exception is occurring.
your doStuff() method is throwing something other than a SQLException and it is not being caught. add a catch(Exception e) block and log that exception and see what happens.
this code sample exhibits the same behaviour you are describing:
public class TryCatchTest {
public static void main(String[] args) {
try {
System.out.println("foo");
throw new NullPointerException();
} finally {
try {
System.out.println("bar");
} catch (Exception e) {
e.printStackTrace();
}
} // exception thrown here
}
}
Close the resources in the reverse order in which they were obtained:
try
{
results.close();
proc.close();
connection.close();
}
catch (Exception e)
{
logger.error(e);
} //<--Exception thrown here. HUH?
I'd also recommend methods like these:
public class DatabaseUtils
{
// similar for ResultSet and Statement
public static void close(Connection c)
{
try
{
if (c != null)
{
c.close();
}
}
catch (SQLException e)
{
// log or print.
}
}
}
It could well be that logger is null.
Hard-to-pinpoint exceptions are often thrown in the exception handler itself.
NullPointerException can not be thrown in a line without a statement.
Check that the class file you are executing is of the same version as the source you view (I have had similar issues when an incorrectly configured classpath contained a class twice and the older version was found first in the classpath, or a recompiled class files for not correctly copied to the web container I used for testing).
Edit: As emh points out, it could also be that exception occured prior to entering the finally block.
I'm 99% sure this is happening in the JDBC driver. For starters, your close statements are backwards. You should close the resultset, the statement and the connection, in that order.
If you are running in an application server which is managing the transactions, then the attempt to commit the transaction may trigger the exception inside the JDBC driver.
It could also be something about how result sets are generated in the stored proceedure, such as accessing one, then accessing another, and then referring back to the first one.
As I said in a comment, never catch an exception that you don't want to deal with. In your code, assuming that it is complete, you are not doing anything interesting with the exception, and it is causing you confusion on where and why the exception is happening. If you really want to do more than log or printStackTrace(), like wrapping it with a domain-specific exception (like your.package.DataAccessException or something), then great.
Do something more like this:
ResultSet results = null;
CallableStatement proc = null;
Connection connection = null;
try {
connection = >
proc = connection.createCallableStatement(..);
results = proc.execute(..);
>
} finally {
try {
if ( results != null ) {
results.close();
}
} catch (Exception e) {
logger.error(e);
}
try {
if ( proc != null ) {
proc.close();
}
} catch (Exception e) {
logger.error(e);
}
try {
if ( connection != null ) {
connection.close();
}
} catch (Exception e) {
logger.error(e);
}
}
And then in the caller:
try {
doStuff();
} catch ( SQLException e ) {
throw new your.package.DataAccessException(e);
// or just let the SQLException propagate upward
} catch ( Exception e ) {
throw new your.package.AppException("omg, crazy pills!", e);
// or, once again, just let the exception
// propagate and don't catch anything
}
So, take-away:
don't log exception where they happen, just pass them on, nested in another exception. You don't want your process to not know whether or not the SQL action succeeded or not. You would rather stop and do something else.
Nest exceptions until the get to the end of the line, that way, you always have the complete trace in the place that you wanted to deal with the exception, not in five places scattered throughout your server log.
Nest exceptions (yes, I said that twice!) so that you don't care where the JVM actually throws the exception from, you have the next exception to follow, telling you it was actually a callable statement, or improper closing of your resources, etc.
Don't nest and throw exceptions from errors caught in your finally code, that will interfere with the original exception and that will be more interesting than the failure to close and statement that didn't get opened in the first place.
Set variables to null before you use them, and then check for null before close()ing them.
Catch each problem in the finally block individually, as you might not be able to close your ResultSet (because some execution error caused it not to open in the first place), but you should still try to close the CallableStatement and Connection, as it is probably unaffected and will still cause you to leak resources.
Hope that helps.