Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issues with Aerospike JDBC Driver: Connection Error and Statement Closure #74

Closed
pavandonade opened this issue Oct 29, 2024 · 7 comments

Comments

@pavandonade
Copy link

Description
I'm encountering a couple of issues while using the Aerospike JDBC driver in my application. I would appreciate any guidance or solutions to these problems.

  1. Connection Issue with DriverManager
    When I attempt to establish a connection to the Aerospike database using DriverManager.getConnection(), I receive an IllegalArgumentException if the Aerospike driver is prioritized with Class.forName("com.aerospike.jdbc.AerospikeDriver"). The error message is:

Exception in thread "main" java.lang.IllegalArgumentException: Cannot parse URL jdbc:oracle:thin:@192.168.xxx.xxx:1521:xyz
at com.aerospike.jdbc.util.URLParser.parseHosts(URLParser.java:128)
at com.aerospike.jdbc.util.URLParser.parseUrl(URLParser.java:82)
at com.aerospike.jdbc.AerospikeConnection.(AerospikeConnection.java:39)
at com.aerospike.jdbc.AerospikeDriver.connect(AerospikeDriver.java:25)
at java.sql.DriverManager.getConnection(DriverManager.java:681)
at java.sql.DriverManager.getConnection(DriverManager.java:229)
at com.icedq.aerospike.OracleMain.main(OracleMain.java:29)

It seems that the Aerospike driver is attempting to parse a connection URL intended for Oracle. How can I resolve this conflict when working with multiple database drivers?

  1. Statement Closure Issue
    While connecting to the Aerospike database, I've observed that java.sql.Statement does not close properly, even after calling statement.close(); in a finally block. When we call statement.isClosed() after closing the statement it returns false. This behavior raises concerns about resource management. Any recommendations on how to ensure statements are correctly closed would be greatly appreciated.

Environment
Aerospike JDBC Driver version: [aerospike-jdbc-1.9.1.jar + its compile time dependencies],
Aerospike JDBC Driver version: uber-aerospike-jdbc-1.7.4.jar
Note: We have tried both the jars
Java version: Java 17
Database: Aerospike

I have attached main program for your reference -

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class OracleMain {

public static void main(String[] args) {
	
	String oraUrl = "jdbc:oracle:thin:@192.168.xxx.xxx:1521:xyz";
	String aerospikeUrl = "jdbc:aerospike:192.168.xxx.xx:4000/bar?tlsEnabled=true&tlsName=aerospikecluster&tlsTruststorePath=D:\\Aerospike\\aerospike-keystore.jks&tlsTruststorePassword=password";
	String query = "SELECT * FROM customer";
	
	Connection aerospikeConn = null;
	Connection oracleConn = null;
	ResultSet aerospikeResultSet = null;
	ResultSet oracleResultSet = null;
	Statement aerospikeStatement = null;
	Statement oracleStatement = null;
	
	try {
		
		Class.forName("com.aerospike.jdbc.AerospikeDriver");
		Class.forName("oracle.jdbc.driver.OracleDriver"); 
					
		oracleConn = DriverManager.getConnection(oraUrl, "username", "password");
		aerospikeConn = DriverManager.getConnection(aerospikeUrl, "username", "password");
		
		System.out.println("Connected to the Oracle database successfully!");			
        System.out.println("Connected to the Aerospike database successfully!");

        aerospikeStatement = aerospikeConn.createStatement();
		aerospikeResultSet = aerospikeStatement.executeQuery(query);
		
        while (aerospikeResultSet.next()) {
        	System.out.println("Aerospike Data:");
        	for (int i = 1; i <= aerospikeResultSet.getMetaData().getColumnCount(); i++) {
				System.out.print(aerospikeResultSet.getString(i) + "\t");
			}
        	System.out.println();
        	break;
        }
        
        oracleStatement = oracleConn.createStatement();
        oracleResultSet = oracleStatement.executeQuery(query);
        
        while (oracleResultSet.next()) {
        	System.out.println("Oracle Data:");
            for (int i = 1; i <= oracleResultSet.getMetaData().getColumnCount(); i++) {
                System.out.print(oracleResultSet.getString(i) + "\t");
            }
            System.out.println();
        	break;
        }
        
	} catch (SQLException | ClassNotFoundException e) {
		System.out.println("Connection failed!");
		e.printStackTrace();
	} finally {
		if (aerospikeConn != null) {
			try {
				oracleResultSet.close();
				aerospikeResultSet.close();
				oracleStatement.close();
				aerospikeStatement.close();
				aerospikeConn.close();
				oracleConn.close();							
				System.out.println("Connection, Statement, Resultset closed.");
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
	
	try {
		System.out.println();
		System.out.println("Aerospike ResultSet isClosed :: " + aerospikeResultSet.isClosed());
		System.out.println("Oracle ResultSet is closed :: " + oracleResultSet.isClosed());
		System.out.println("Aerospike Statement isClosed :: " + aerospikeStatement.isClosed());
		System.out.println("Oracle Statement is closed :: " + oracleStatement.isClosed());
		System.out.println("Oracle Connection is closed :: " + oracleConn.isClosed());
		System.out.println("Aerospike Connection isClosed :: " + aerospikeConn.isClosed());

	} catch (SQLException e) {
		e.printStackTrace();
	}
	    
}

}

@reugn
Copy link
Member

reugn commented Oct 30, 2024

Hi @pavandonade,

  1. PR FMWK-587 Return null for inapplicable URLs in driver connect #75 addresses the issue of the driver parsing URLs that are not intended for processing.
  2. PR FMWK-588 Handle closed state in statements #76 adds handling of the closed state for statements. Since there are no resources to close, this change is cosmetic and ensures consistent behavior.

To test the fixes, you can build and install the driver locally.

Feel free to reach out if you have any questions or encounter any issues.

@pavandonade
Copy link
Author

Hi @reugn
Thank you for your prompt response and the proposed fixes in PRs FMWK-587 and FMWK-588. I appreciate the effort to address the reported issues.

Unfortunately, I am still encountering the IllegalArgumentException after testing the driver built with these changes. The issue arises under the following specific conditions:

Scenario 1: Aerospike Driver Loaded First

When the Aerospike JDBC driver is loaded before the Oracle JDBC driver using Class.forName(), and then a connection to the Oracle database is attempted, the following sequence triggers the exception:

Class.forName("com.aerospike.jdbc.AerospikeDriver");
Class.forName("oracle.jdbc.driver.OracleDriver");

Connection oracleConn = DriverManager.getConnection(oraUrl, "username", "password");
Connection aerospikeConn = DriverManager.getConnection(aerospikeUrl, "username", "password");

This results in:

Exception in thread "main" java.lang.IllegalArgumentException: Cannot parse URL jdbc:oracle:thin:@192.168.xxx.xxx:1521:orcl
at com.aerospike.jdbc.model.DriverConfiguration.parseHosts(DriverConfiguration.java:118)
at com.aerospike.jdbc.model.DriverConfiguration.parse(DriverConfiguration.java:59)
at com.aerospike.jdbc.AerospikeConnection.(AerospikeConnection.java:49)
at com.aerospike.jdbc.AerospikeDriver.connect(AerospikeDriver.java:37)
at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:681)
at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:229)
at com.icedq.Aerospike.main(Aerospike.java:29)

Scenario 2: Oracle Driver Loaded First

However, when the driver loading order is reversed, with the Oracle JDBC driver loaded before the Aerospike driver, the connections are successful:

Class.forName("oracle.jdbc.driver.OracleDriver");
Class.forName("com.aerospike.jdbc.AerospikeDriver");

Connection oracleConn = DriverManager.getConnection(oraUrl, "username", "password");
Connection aerospikeConn = DriverManager.getConnection(aerospikeUrl, "username", "password");

This indicates that the Aerospike driver might be incorrectly attempting to parse the Oracle JDBC URL, despite the intended fix in FMWK-587.

Additional Observation:

I have also observed that aerospikeStatement.isClosed() consistently returns false even after explicitly calling aerospikeStatement.close() within a finally block. This behavior is unexpected, as the finally block guarantees execution, and no exceptions occur during the statement closure.

Environment Details:

Aerospike JDBC Driver version: uber-aerospike-jdbc-1.9.1.jar
Oracle JDBC Driver version: ojdbc8.jar
Java version: Java 17
Please let me know if you require any further information or a more detailed code example to assist in your investigation. I would be happy to provide any assistance needed to resolve these issues.

@reugn
Copy link
Member

reugn commented Nov 4, 2024

@pavandonade, please use the locally built driver from the main branch, not the released version 1.9.1.

@pavandonade
Copy link
Author

Hi @reugn

That worked perfectly!  Thanks for pointing me to the main branch driver. It seems the released version (1.9.1) was causing the issue. I appreciate the quick and accurate solution. Now I'm facing a situation where the program doesn't terminate even after fetching and closing all resource correctly. It should terminate main program after execution. Any suggestions would be appreciated.

@reugn
Copy link
Member

reugn commented Nov 4, 2024

To close the global client's EventLoops add EventLoopProvider.close(); at the end of your main function.

@pavandonade
Copy link
Author

Hello @reugn,
Thanks again for the suggestion! Adding EventLoopProvider.close(); resolved the issue. I was really stuck on that, so I'm very grateful for your assistance.

@reugn
Copy link
Member

reugn commented Nov 12, 2024

Version 1.9.2 has been released.

@reugn reugn closed this as completed Nov 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants