How to fix RuntimeException? - java

import java.sql.Connection;
public static void main(String[] args) throws SQLException, RuntimeException {
try{
DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver());
String connectionURL="jdbc:mysql://localhost:3306/aaa?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC";
String login="root";
String password="aaa";
try (Connection conn = DriverManager.getConnection(connectionURL, login, password)) {
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM Lista1");
while(rs.next()) {
System.out.println(rs.getString("nazwa"));
}
rs.close();
stmt.close();
}
}
catch(SQLException e) {
System.out.println("Blad polaczenia:");
e.printStackTrace();
}
catch(RuntimeException e) {
System.out.println("Blad polaczenia:");
e.printStackTrace();
}
The console log throws:
Exception in thread "main" java.lang.RuntimeException:
at cccc.web.Main.main(Main.java:1)
I tried to delete return, but it still threw bad issue.
I tried many things but I don't know how to fix it.
I don't know how to solve it. And I spent many many many times to fight with it!!!!

The exception object contains two things that tell you what happened: the specific type of the exception (RuntimeException is a base), and if you're lucky, a text message telling you what the problem is.
Print them in your exception handler.
System.out.println("Exception: " + e)
And, of course, the stacktrace tells you the exact line of your source file that caused the problem.
This is not really a matter of 'fixing' an exception, it's a matter of understanding what is going on and writing code to handle that situation.

When an error tells you that the exception happened on the first line, that very much looks like a parsing issue. Take a look here:
try (Connection conn = DriverManager.getConnection(connectionURL, login, password)) {
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM Lista1");
while(rs.next()) {
System.out.println(rs.getString("nazwa"));
}
rs.close();
stmt.close();
}
The code above is a try without a catch. It's inside an outer try. But once you are using a try, you need a catch. Fix this parsing error and let's see whether there are other problems as well.

Related

Tomcat Connection Pool abandoned issue

I'm struggling with a Tomcat connection pool error.The below error is thrown at runtime after running a simple stored procedure that generates a String value.
WARNING: Connection has been abandoned PooledConnection[ConnectionID:45 ClientConnectionId: 7817280c-3f7e-4239-a009-3aedd0a855e8]:java.lang.Exception
at org.apache.tomcat.jdbc.pool.ConnectionPool.getThreadDump(ConnectionPool.java:1096)
at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:799)
at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:648)
at org.apache.tomcat.jdbc.pool.ConnectionPool.getConnection(ConnectionPool.java:200)
at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:128)
at util.ThreadLocalUtil.getConnection(ThreadLocalUtil.java:55)
at webapp.dao.WebApplicationDAO.getConnection(WebApplicationDAO.java:30)
at webapp.dao.AccountDAO.generateAccountId(AccountDAO.java:827)
at webapp.bo.Account.generateUserAccountId(Account.java:285)
at webapp.actions.AddUserAccountUNZAction.execute(AddUserAccountUNZAction.java:79)
at org.apache.struts.chain.commands.servlet.ExecuteAction.execute(ExecuteAction.java:58)
at org.apache.struts.chain.commands.AbstractExecuteAction.execute(AbstractExecuteAction.java:67)
at org.apache.struts.chain.commands.ActionCommandBase.execute(ActionCommandBase.java:51)
My knowledge of that error is that a connection was opened and not closed. The connection is opened when running the stored proc in the account dao. Below is the block of code which calls the stored procedure.
Connection conn = null;
CallableStatement stmt = null;
ResultSet rs = null;
try {
conn = getConnection();
stmt = conn.prepareCall(sqlWebAppGenerateUserId);
stmt.setString(1, base);
rs = stmt.executeQuery();
String res = null;
if (rs.next()) {
res = rs.getString(1);
}
if (res == null) {
throw new RuntimeException("Failed to generate user id.");
}
return res;
} catch (SQLException e) {
LOG.error("{}", e);
throw new RuntimeException(e);
}finally {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
LOG.error(e.getMessage(), e);
}
}
if (rs != null) {
try {
rs.close();
conn.close();
} catch (SQLException e) {
LOG.error(e.getMessage(), e);
}
}
}
As you can see, I'm using a finally block to close the connection etc.
I'm at a loss to explain the reason why the error is being thrown still and as to how I can debug and solve this issue. Any help would be greatly appreciated
You close conn only if rs != null, meaning that every time a query fails the connection won't be closed.
I also recommend switching to try-with-resources instead of writing clumsy finally blocks which may cause bugs.
What #Kayaman said. Also if the statement execution takes longer than removeAbandonedTimeout this can happen.
#Kayaman and #Gorazd thank you for the advice. The issue with down to missing jar files in the tomcat lib folder. More specifically mail-1.4.jar.
As this jar file was missing, a function that sends emails failed. Previous to the call to send the mail, connection.autocommit is set to true. After the mail sends it will set autocommit back to false. This to me looks like where the abandoned error was occurring from.
When looking through logs file I found the mail sending error. This was in actual fact the true error whereas the abandoned error can be looked at as a red herring.

maximum open cursors exceeded exception in java code

this my code to execute update query
public boolean executeQuery(Connection con,String query) throws SQLException
{
boolean flag=false;
try
{
Statement st = con.createStatement();
flag=st.execute(query);
st.close();
st=null;
flag=true;
}
catch (Exception e)
{
flag=false;
e.printStackTrace();
throw new SQLException(" UNABLE TO FETCH INSERT");
}
return flag;
}
maximum open cursor is set to 4000
code is executing
update tableA set colA ='x',lst_upd_date = trunc(sysdate) where trunc(date) = to_date('"+date+"','dd-mm-yyyy')
update query for around 8000 times
but after around 2000 days its throwing exception as "maximum open cursors exceeded"
please suggest code changes for this.
#TimBiegeleisen here is the code get connecttion
public Connection getConnection(String sessId)
{
Connection connection=null;
setLastAccessed(System.currentTimeMillis());
connection=(Connection)sessionCon.get(sessId);
try
{
if(connection==null || connection.isClosed() )
{
if ( ds == null )
{
InitialContext ic = new InitialContext();
ds = (DataSource) ic.lookup("java:comp/env/iislDB");
}
connection=ds.getConnection();
sessionCon.put(sessId, connection);
}
}
catch (SQLException e)
{
e.printStackTrace();
}
catch (Exception e)
{
e.printStackTrace();
}
return connection;
}
`
error stack is as bellow
java.sql.SQLException: ORA-01000: maximum open cursors exceeded
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:180)
at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:208)
at oracle.jdbc.ttc7.Oopen.receive(Oopen.java:118)
at oracle.jdbc.ttc7.TTC7Protocol.open(TTC7Protocol.java:472)
at oracle.jdbc.driver.OracleStatement.<init>(OracleStatement.java:499)
at oracle.jdbc.driver.OracleConnection.privateCreateStatement(OracleConnection.java:683)
at oracle.jdbc.driver.OracleConnection.createStatement(OracleConnection.java:560)
at org.apache.tomcat.dbcp.dbcp.DelegatingConnection.createStatement(DelegatingConnection.java:257)
at org.apache.tomcat.dbcp.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.createStatement(PoolingDataSource.java:216)
at com.iisl.business.adminbo.computeindex.MoviIndexComputeBO.calculateMoviValue(MoviIndexComputeBO.java:230)
Your code has a cursor leak. That's what is causing the error. It seems unlikely that your code can really go 2000 days (about 5.5 years) before encountering the error. If that was the case, I'd wager that you'd be more than happy to restart a server twice a decade.
In your try block, you create a Statement. If an exception is thrown between the time that the statement is created and the time that st.close() is called, your code will leave the statement open and you will have leaked a cursor. Once a session has leaked 4000 cursors, you'll get the error. Increasing max_open_cursors will merely delay when the error occurs, it won't fix the underlying problem.
The underlying problem is that your try/ catch block needs a finally that closes the Statement if it was left open by the try. For this to work, you'd need to declare st outside of the try
finally {
if (st != null) {
st.close();
}
}
As mentioned in another response you will leak cursors if an exception is thrown during the statement execution because st.close() won't be executed. You can use Java's try-with-resources syntax to be sure that your statement object is closed:
try (Statement st = con.createStatement())
{
flag=st.execute(query);
flag=true;
}
catch (Exception e)
{
flag=false;
e.printStackTrace();
throw new SQLException(" UNABLE TO FETCH INSERT");
}
return flag;
One of quickest solution is to increase cursor that each connection can handle by issuing following command on SQL prompt:
alter system set open_cursors = 1000
Also, add finally block in your code and close the connection to help closing cursors when ever exception occurs.
Also, run this query to see where actually cursor are opened.
select sid ,sql_text, count(*) as "OPEN CURSORS", USER_NAME from v$open_cursor
finally {
if (connection!=null) {
connection.close();
}

JFrame in Eclipse with SQLite

I found this example to connect with a SQLite database:
try{
Class.forName("org.sqlite.JDBC");
connection = DriverManager.getConnection("jdbc:sqlite:C:\\pruebaSQLite\\dbTest.sqlite");
System.out.println("Conectado a la base de datos SQLite ");
}catch(Exception e){
System.out.println(e);
}
it's working fine but I try to connect a JAVA application using it like this:
try {
Class.forName("org.sqlite.JDBC");
Connection con = DriverManager.getConnection("jdbc:sqlite:C:\\LoginJava2\\myDB.sqlite");
PreparedStatement pstm = con.prepareStatement("insert into hell(username,pssword) " +
"values ('"+tfUname.getText()+"','"+tfUpass.getText()+"')");
pstm.close();
con.close();
JOptionPane.showMessageDialog(null,"Congrats, you have been registered succesfully");
RegisterWindow rw = new RegisterWindow();
rw.setVisible(false);
pack();
dispose();
} catch(SQLException ex) {
setTitle(ex.toString());
}
the line: "Class.forName("org.sqlite.JDBC");" give me the next error:
Unhandled exception type ClassNotFoundException
if I remove that line the program runs fine but when I execute the action, it gives me the next exception:
java.sql.SQLException: No suitable driver found for jdbc:sqlite:C:\\LoginJava2\\myDB.sqlite
That's weird because I'm using the same jar in both examples.
I'm using the next jar file: "sqlitejdbc-v056"
if someone could help me how to fix the error in the "line Class.forName("org.sqlite.JDBC");"
or if I'm doing someting wrong in the URL connection... I will apreciate!!
Thanks and sorry for my english!!
if someone clud help me how to fix the error in the "line Class.forName("org.sqlite.JDBC");" or if I'm doing someting wrong in the URL connection... I will apreciate!!
The error message is telling you exactly what needs to be fixed -- you need to handle the exception that it mentions, the ClassNotFoundException.
The main thing you should notice is that catch blocks in your two code examples are different, and one works while the other doesn't. Note that I don't recommend that you use the first catch block, the one that catches Exception, even though it works, since catching all Exceptions is usually not a good idea and prevents exceptions that should percolate to a higher level from doing so. Instead you should catch the explicit Exceptions that need to be caught, here SQLException and ClassNotFoundException.
The Exception Tutorial should help explain this more fully to you with code examples. How you catch this also will depend on if you're working with Java 1.7 or prior versions.
To Fix the problem I added the next to the code:
try {
Class.forName("org.sqlite.JDBC");
Connection con = DriverManager.getConnection("jdbc:sqlite:C:\\LoginJava2\\myDB.sqlite");
Statement com = con.createStatement();
com.executeUpdate("insert into hell(username,pssword) " +
"values ('"+tfUname.getText()+"','"+tfUpass.getText()+"')");
con.close();
JOptionPane.showMessageDialog(null,"Congrats, you have been registered succesfully");
RegisterWindow rw = new RegisterWindow();
rw.setVisible(false);
pack();
dispose();
} catch(SQLException ex) {
setTitle(ex.toString());
}
catch(ClassNotFoundException e) { // I added this catch to handle the exception
setTitle(e.toString());
}

Java 7 Automatic Resource Management JDBC (try-with-resources statement)

How to integrate the common JDBC idiom of creating/receiving a connection, querying the database and possibly processing the results with Java 7's automatic resource management, the try-with-resources statement? (Tutorial)
Before Java 7, the usual pattern was something like this:
Connection con = null;
PreparedStatement prep = null;
try{
con = getConnection();
prep = prep.prepareStatement("Update ...");
...
con.commit();
}
catch (SQLException e){
con.rollback();
throw e;
}
finally{
if (prep != null)
prep.close();
if (con != null)
con.close();
}
With Java 7 you can go for:
try(Connection con = getConnection(); PreparedStatement prep = con.prepareConnection("Update ..."){
...
con.commit();
}
This will close the Connection and the PreparedStatement, but what about the rollback? I cannot add a catch clause containing the rollback, because the connection is only available within the try block.
Do you still define the connection outside of the try block? What is the best practice here, especially if connection pooling is used?
try(Connection con = getConnection()) {
try (PreparedStatement prep = con.prepareConnection("Update ...")) {
//prep.doSomething();
//...
//etc
con.commit();
} catch (SQLException e) {
//any other actions necessary on failure
con.rollback();
//consider a re-throw, throwing a wrapping exception, etc
}
}
According to the oracle documentation, you can combine a try-with-resources block with a regular try block. IMO, the above example captures the correct logic, which is:
Attempt to close the PreparedStatement if nothing goes wrong
If something goes wrong in the inner block, (no matter what is is) roll back the current transaction
Attempt to close the connection no matter what
If something goes wrong closing the connection, you can't rollback the transaction (as that's a method on the connection, which is now in indeterminate state), so don't try
In java 6 and earlier, I would do this with a triply nested set of try blocks (outer try-finally, middle try-catch, inner try-finally). ARM syntax does make this terser.
IMO, declaring Connection and PreparedStatement outside try-catch is the best way available in this case.
If you want to use pooled connection in transaction, you should use it in this way:
try (Connection conn = source.getConnection()) {
conn.setAutoCommit(false);
SQLException savedException = null;
try {
// Do things with connection in transaction here...
conn.commit();
} catch (SQLException ex) {
savedException = ex;
conn.rollback();
} finally {
conn.setAutoCommit(true);
if(savedException != null) {
throw savedException;
}
}
} catch (SQLException ex1) {
throw new DataManagerException(ex1);
}
This sample code handles setting autocommit values.
NOTE, that using savedException does save exception in case that conn.rollback() throws another. This way, finally block will throw "right" exception.

syntax warning showing: exception is never thrown in body of try statement

public class SetupConnection{
public static Statement setCon(){
Connection con=null;
Statement st=null;
try{
Class.forName("com.mysql.jdbc.Driver").newInstance();
con=DriverManager.getConnection(
"jdbc:mysql://localhost:3306/zomatocrm","root","");
st = con.createStatement();
}
catch(ConnectException err){
JOptionPane.showMessageDialog(null, "Connection refused!!!");
System.out.println(err.getMessage());
}
catch(Exception e){
System.out.println(e.getMessage());
}
return st;
}
The warning:
exception is never thrown in body of try statement
is coming up at the catch(ConnectException){ line.
None of the code in your try block:
Class.forName("com.mysql.jdbc.Driver").newInstance();
con=DriverManager.getConnection(
"jdbc:mysql://localhost:3306/zomatocrm","root","");
st = con.createStatement();
...can ever throw a ConnectException. Therefore the compiler is warning you that this catch clause:
catch(ConnectException err){
JOptionPane.showMessageDialog(null, "Connection refused!!!");
System.out.println(err.getMessage());
}
is redundant. If you remove it, the warning will go away.
getConnection and createStatement throw SQLException, which is caught in your second catch block. ConnectException is never thrown...
Note, if the connection to the database fails due to network problems, you'll still only get a SQLException, so catching that would be better and if you want to determine whether there was a networking problem you could check the SQLState (according to the manual):
try {
...
} catch (SQLException sqle) {
if ("08S01".equals(sqle.getSQLState())) {
JOptionPane.showMessageDialog(null, "Connection refused (or networking problem)!!!");
System.out.println(err.getMessage());
}
}
Also (as a general point, not related to this error), your method creates a connection (con object), but no reference to it is ever returned, so how are you closing the connection? Not closing a connection can lead to a connection leak, which will cause you problems.
Your real question has been answered by others. I just want to point out that this ...
catch (Exception e) {
System.out.println(e.getMessage());
}
return st;
... is really bad code.
What you are doing is dumping a stacktrace to stderr, and then continuing as if nothing bad has happened. The problem is:
the Exception you just caught could be caused by all sorts of things, some of which should not be ignored, and
the stderr stream might be connected to nothing,
(maybe worse) the raw stacktrace could be displayed to a non-Java literate user who won't understand it and who is likely to either ignore it or freak out!

Categories

Resources