Issue Details (XML | Word | Printable)

Key: JDBC-538
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Critical Critical
Assignee: Mark Rotteveel
Reporter: Josef Melich
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
Jaybird JCA/JDBC Driver

When the Exception is thrown out from the constructor in: AbstractPreparedStatement - line: 151, finalizer tries to remove FBstatement from activeStatements collection and warn appears.

Created: 18/Jul/18 12:30 PM   Updated: 07/Sep/18 03:41 PM
Component/s: JDBC driver
Affects Version/s: Jaybird 3.0.4
Fix Version/s: Jaybird 3.0.5, Jaybird 4

Environment: Windows 10, Java 8, Jaybird 3.0.3 (same problem on 3.0.4)


 Description  « Hide
If you try to executeQuery() on statement e.g.: SELECT MAX(num) FROM nums
And the table "nums" is not exists, the SQLException is thrown in FBConnection - line: 1191 and next command: activeStatements.add(stmt); wont proceed. The problem is, that then the GarbageCollector tries to finalize the uncreated Object and calls method: "void notifyStatementClosed(FBStatement stmt)", which loggs: "log.warn("Specified statement was not created by this connection: " + stmt);" because the uncreated PreparedStatement throws exception before and was not added to the collection: "activeStatements".

Finalization is called when the ancestor constructor of java.lang.Object has ended successfully, refer here: https://stackoverflow.com/questions/14483279/can-finalize-be-called-after-a-constructor-throws-an-exception

Your algorithm simply does not count with the fact that if the exception is throwed in the constructor, the statement will be closed too. (Then the warn appears.)

Thank you for solving :)



 All   Comments   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Mark Rotteveel added a comment - 18/Jul/18 02:58 PM
Do you mean when using `Connection.prepareStatement`, because I don't see how this could occur with `executeQuery` on a normal Statement object.

Mark Rotteveel added a comment - 18/Jul/18 04:07 PM
The best solution would probably be to move prepare from the constructor, to a separate method, or making registration a side-effect of the constructor. However that has knock-on effects elsewhere, so instead I'll check if it is a prepared statement that is not fully initialized and then not log the warning.

I'll consider a cleaner solution for Jaybird 4 or later.


Josef Melich added a comment - 19/Jul/18 06:18 AM
Yes, sorry for delay, the callstack of calling constructor is here:

at org.firebirdsql.jdbc.FBConnection.prepareStatement(FBConnection.java:1191)
at org.firebirdsql.jdbc.FBConnection.prepareStatement(FBConnection.java:961)
at org.firebirdsql.jdbc.FBConnection.prepareStatement(FBConnection.java:915)
at org.firebirdsql.jdbc.FBConnection.prepareStatement(FBConnection.java:324)

Can I ask when the version 3.0.5 will come out? Thank you :)

Mark Rotteveel added a comment - 21/Jul/18 07:50 AM
I don't have a definitive release date yet, but probably somewhere in August. If this is really a big issue for you, I could build a snapshot version for you. Let me know if you need one.

Mark Rotteveel added a comment - 21/Jul/18 08:18 AM
Committed the same fix for Jaybird 4. Created an improvement ticket to look into a cleaner solution for Jaybird 5.

Josef Melich added a comment - 23/Jul/18 06:42 AM
No problem, the August will be fine. :) Thank you.