Ultimate JDBC Connection Pool - Java 6 compatible version providing high-performance database connection pooling
—
Advanced functionality including JNDI integration, custom connection handling, proxy system components, utility classes, and specialized features for advanced use cases and custom integrations.
Support for JNDI-based DataSource deployment and lookup in enterprise environments.
public class HikariJNDIFactory implements ObjectFactory {
/**
* Create HikariDataSource instance from JNDI reference.
* Used by application servers for JNDI DataSource deployment.
*
* @param obj JNDI reference object
* @param name JNDI name
* @param nameCtx JNDI naming context
* @param environment JNDI environment
* @return HikariDataSource instance or null
* @throws Exception on creation error
*/
public Object getObjectInstance(Object obj, Name name, Context nameCtx,
Hashtable<?, ?> environment) throws Exception;
}Interface for customizing connections before they are added to the pool (deprecated in favor of connection initialization SQL).
public interface IConnectionCustomizer {
/**
* Customize a raw JDBC connection before it is added to the pool.
*
* @param connection raw JDBC connection to customize
* @throws SQLException if customization fails
* @deprecated Use connectionInitSql configuration property instead
*/
void customize(Connection connection) throws SQLException;
}Standalone DataSource implementation for direct JDBC driver usage.
public class DriverDataSource implements DataSource {
/**
* Create DataSource with driver configuration.
*
* @param jdbcUrl JDBC URL
* @param driverClassName JDBC driver class name
* @param properties driver properties
* @param username database username
* @param password database password
*/
public DriverDataSource(String jdbcUrl, String driverClassName,
Properties properties, String username, String password);
/**
* Get connection using configured credentials.
*
* @return new database connection
* @throws SQLException on connection error
*/
public Connection getConnection() throws SQLException;
/**
* Get connection (ignores username/password parameters).
*
* @param username ignored
* @param password ignored
* @return new database connection
* @throws SQLException on connection error
*/
public Connection getConnection(String username, String password) throws SQLException;
/**
* Get log writer (throws SQLFeatureNotSupportedException).
*
* @return never returns normally
* @throws SQLException always thrown
*/
public PrintWriter getLogWriter() throws SQLException;
/**
* Set log writer (throws SQLFeatureNotSupportedException).
*
* @param logWriter ignored
* @throws SQLException always thrown
*/
public void setLogWriter(PrintWriter logWriter) throws SQLException;
/**
* Set login timeout in seconds.
*
* @param seconds timeout in seconds
* @throws SQLException on error
*/
public void setLoginTimeout(int seconds) throws SQLException;
/**
* Get login timeout in seconds.
*
* @return timeout in seconds
* @throws SQLException on error
*/
public int getLoginTimeout() throws SQLException;
/**
* Get parent logger.
*
* @return parent logger
* @throws SQLFeatureNotSupportedException if not supported
*/
public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException;
/**
* Unwrap to specified interface (throws SQLFeatureNotSupportedException).
*
* @param iface target interface
* @return never returns normally
* @throws SQLException always thrown
*/
public <T> T unwrap(Class<T> iface) throws SQLException;
/**
* Check if wrapper for interface (always returns false).
*
* @param iface target interface
* @return false
* @throws SQLException on error
*/
public boolean isWrapperFor(Class<?> iface) throws SQLException;
/**
* Shutdown the DataSource (no-op implementation).
*/
public void shutdown();
}Specialized collections optimized for HikariCP's internal use.
public class FastList<T> {
/**
* Create FastList with default capacity (32).
*
* @param clazz element class for array creation
*/
public FastList(Class<?> clazz);
/**
* Create FastList with specified capacity.
*
* @param clazz element class for array creation
* @param capacity initial capacity
*/
public FastList(Class<?> clazz, int capacity);
/**
* Add element to the end of the list.
* No bounds checking for performance.
*
* @param element element to add
*/
public void add(T element);
/**
* Get element at specified index.
* No bounds checking for performance.
*
* @param index element index
* @return element at index
*/
public T get(int index);
/**
* Remove and return the last element.
*
* @return last element
*/
public T removeLast();
/**
* Remove specified element using identity comparison.
*
* @param element element to remove
*/
public void remove(T element);
/**
* Clear all elements from the list.
*/
public void clear();
/**
* Get current number of elements.
*
* @return current size
*/
public int size();
}Lock-free concurrent collection used internally by HikariCP for optimal performance.
public class ConcurrentBag<T extends IConcurrentBagEntry> {
// Lock-free concurrent collection for connection pooling
// Optimized for high-performance access patterns
}
public interface IConcurrentBagEntry {
// Interface for objects stored in ConcurrentBag
// Provides state management for pooled connections
}
public interface IBagStateListener {
// Listener interface for ConcurrentBag state changes
// Used for pool management notifications
}Default thread factory implementation for HikariCP thread pools.
public class DefaultThreadFactory implements ThreadFactory {
// Creates daemon threads for HikariCP internal operations
// Provides proper naming and exception handling
}Utility for setting Java Bean properties from Properties objects.
public class PropertyBeanSetter {
// Utility for reflective property setting
// Handles type conversion and bean property mapping
}Collection of utility methods used throughout HikariCP.
public class UtilityElf {
// General utility methods for:
// - String manipulation
// - Numeric operations
// - Validation helpers
// - System property access
}Utilities for dynamic class loading and reflection operations.
public class ClassLoaderUtils {
// Class loading utilities for:
// - Dynamic driver loading
// - Reflection operations
// - Classpath management
}Specific exception types used by HikariCP.
public class PoolInitializationException extends RuntimeException {
/**
* Construct with cause.
*
* @param t underlying cause of initialization failure
*/
public PoolInitializationException(Throwable t);
}<!-- In server.xml or equivalent for JNDI deployment -->
<Resource name="jdbc/MyDataSource"
auth="Container"
factory="com.zaxxer.hikari.HikariJNDIFactory"
type="javax.sql.DataSource"
jdbcUrl="jdbc:postgresql://localhost/mydb"
username="dbuser"
password="dbpass"
maximumPoolSize="20"
minimumIdle="5"
connectionTimeout="30000"
idleTimeout="600000"
poolName="JNDIPool" />import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
// Lookup DataSource from JNDI
Context ctx = new InitialContext();
DataSource dataSource = (DataSource) ctx.lookup("jdbc/MyDataSource");
// Use the DataSource normally
try (Connection conn = dataSource.getConnection()) {
// Database operations
}import com.zaxxer.hikari.util.DriverDataSource;
import java.util.Properties;
// Create properties for driver configuration
Properties driverProps = new Properties();
driverProps.setProperty("useSSL", "false");
driverProps.setProperty("serverTimezone", "UTC");
driverProps.setProperty("cachePrepStmts", "true");
// Create DriverDataSource
DriverDataSource driverDataSource = new DriverDataSource(
"jdbc:mysql://localhost:3306/mydb",
"com.mysql.jdbc.Driver",
driverProps,
"user",
"password"
);
// Use directly or wrap with HikariCP
HikariConfig config = new HikariConfig();
config.setDataSource(driverDataSource);
config.setMaximumPoolSize(10);
HikariDataSource pooledDataSource = new HikariDataSource(config);import com.zaxxer.hikari.IConnectionCustomizer;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
// Custom connection customizer (deprecated - use connectionInitSql instead)
public class MyConnectionCustomizer implements IConnectionCustomizer {
@Override
public void customize(Connection connection) throws SQLException {
try (Statement stmt = connection.createStatement()) {
// Set session variables
stmt.execute("SET SESSION sql_mode = 'STRICT_TRANS_TABLES'");
stmt.execute("SET SESSION time_zone = '+00:00'");
}
}
}
// Configure with customizer (deprecated approach)
HikariConfig config = new HikariConfig();
config.setConnectionCustomizer(new MyConnectionCustomizer());
// Modern approach - use connectionInitSql instead
HikariConfig modernConfig = new HikariConfig();
modernConfig.setConnectionInitSql(
"SET SESSION sql_mode = 'STRICT_TRANS_TABLES'; " +
"SET SESSION time_zone = '+00:00';"
);import com.zaxxer.hikari.proxy.IHikariConnectionProxy;
// Get connection from HikariCP
try (Connection conn = dataSource.getConnection()) {
// Cast to HikariCP proxy interface
if (conn instanceof IHikariConnectionProxy) {
IHikariConnectionProxy hikariConn = (IHikariConnectionProxy) conn;
// Access pool-specific information
PoolBagEntry bagEntry = hikariConn.getPoolBagEntry();
System.out.println("Connection created at: " + bagEntry.getCreationTime());
System.out.println("Last accessed: " + bagEntry.getLastAccess());
// The proxy automatically handles:
// - Statement tracking and cleanup
// - Connection state management
// - Leak detection
// - Exception analysis for connection validity
}
// Use connection normally - proxy behavior is transparent
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM users WHERE id = ?");
stmt.setInt(1, 123);
ResultSet rs = stmt.executeQuery();
// ResultSet and Statement are also proxied automatically
}import com.zaxxer.hikari.util.FastList;
// Create high-performance list for connection objects
FastList<Connection> connectionList = new FastList<>(Connection.class, 10);
// Add connections (no bounds checking for performance)
connectionList.add(connection1);
connectionList.add(connection2);
connectionList.add(connection3);
// Access by index (no bounds checking)
Connection firstConn = connectionList.get(0);
// Remove last connection efficiently
Connection lastConn = connectionList.removeLast();
// Remove specific connection by identity
connectionList.remove(connection2);
// Get current size
int size = connectionList.size();
// Clear all connections
connectionList.clear();import com.zaxxer.hikari.util.DefaultThreadFactory;
import java.util.concurrent.ThreadFactory;
// Use HikariCP's default thread factory for consistency
ThreadFactory hikariThreadFactory = new DefaultThreadFactory();
// Configure HikariCP with custom thread factory
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:postgresql://localhost/mydb");
config.setUsername("user");
config.setPassword("password");
config.setThreadFactory(hikariThreadFactory);
// Or create custom thread factory following HikariCP patterns
ThreadFactory customFactory = new ThreadFactory() {
private int counter = 0;
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r, "MyApp-HikariCP-" + (++counter));
thread.setDaemon(true); // Important: make daemon threads
thread.setUncaughtExceptionHandler((t, e) -> {
System.err.println("Uncaught exception in thread " + t.getName() + ": " + e.getMessage());
});
return thread;
}
};
config.setThreadFactory(customFactory);import com.zaxxer.hikari.util.PropertyBeanSetter;
import java.util.Properties;
// Example of using PropertyBeanSetter for custom configuration objects
public class MyDatabaseConfig {
private String host;
private int port;
private boolean useSSL;
// Getters and setters...
public void setHost(String host) { this.host = host; }
public void setPort(int port) { this.port = port; }
public void setUseSSL(boolean useSSL) { this.useSSL = useSSL; }
}
// Configure from properties
Properties props = new Properties();
props.setProperty("host", "localhost");
props.setProperty("port", "5432");
props.setProperty("useSSL", "true");
MyDatabaseConfig config = new MyDatabaseConfig();
PropertyBeanSetter.setTargetFromProperties(config, props);import com.zaxxer.hikari.pool.PoolInitializationException;
try {
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:invalid://invalid");
config.setInitializationFailFast(true); // Fail fast on invalid config
HikariDataSource dataSource = new HikariDataSource(config);
} catch (PoolInitializationException e) {
System.err.println("Pool initialization failed: " + e.getMessage());
Throwable cause = e.getCause();
if (cause != null) {
System.err.println("Root cause: " + cause.getMessage());
}
// Handle initialization failure appropriately
// - Log error details
// - Use fallback DataSource
// - Retry with different configuration
// - Fail application startup
}import com.zaxxer.hikari.proxy.IHikariConnectionProxy;
// Custom connection monitoring
public class ConnectionMonitor {
public static void monitorConnection(Connection conn) {
if (conn instanceof IHikariConnectionProxy) {
IHikariConnectionProxy proxy = (IHikariConnectionProxy) conn;
PoolBagEntry entry = proxy.getPoolBagEntry();
// Log connection usage
long ageMs = System.currentTimeMillis() - entry.getCreationTime();
System.out.println("Using connection age: " + ageMs + "ms");
// Track connection in custom metrics
MyMetrics.recordConnectionAge(ageMs);
MyMetrics.incrementActiveConnections();
}
}
}
// Use in application
try (Connection conn = dataSource.getConnection()) {
ConnectionMonitor.monitorConnection(conn);
// Database operations
// ...
} // Connection automatically returned to pool with cleanupInstall with Tessl CLI
npx tessl i tessl/maven-com-zaxxer--hikari-cp-java6