0
# Utilities and Advanced Features
1
2
Advanced functionality including JNDI integration, custom connection handling, proxy system components, utility classes, and specialized features for advanced use cases and custom integrations.
3
4
## Capabilities
5
6
### JNDI Integration
7
8
Support for JNDI-based DataSource deployment and lookup in enterprise environments.
9
10
```java { .api }
11
public class HikariJNDIFactory implements ObjectFactory {
12
/**
13
* Create HikariDataSource instance from JNDI reference.
14
* Used by application servers for JNDI DataSource deployment.
15
*
16
* @param obj JNDI reference object
17
* @param name JNDI name
18
* @param nameCtx JNDI naming context
19
* @param environment JNDI environment
20
* @return HikariDataSource instance or null
21
* @throws Exception on creation error
22
*/
23
public Object getObjectInstance(Object obj, Name name, Context nameCtx,
24
Hashtable<?, ?> environment) throws Exception;
25
}
26
```
27
28
29
### Connection Customization
30
31
Interface for customizing connections before they are added to the pool (deprecated in favor of connection initialization SQL).
32
33
```java { .api }
34
public interface IConnectionCustomizer {
35
/**
36
* Customize a raw JDBC connection before it is added to the pool.
37
*
38
* @param connection raw JDBC connection to customize
39
* @throws SQLException if customization fails
40
* @deprecated Use connectionInitSql configuration property instead
41
*/
42
void customize(Connection connection) throws SQLException;
43
}
44
```
45
46
### Utility DataSource
47
48
Standalone DataSource implementation for direct JDBC driver usage.
49
50
```java { .api }
51
public class DriverDataSource implements DataSource {
52
/**
53
* Create DataSource with driver configuration.
54
*
55
* @param jdbcUrl JDBC URL
56
* @param driverClassName JDBC driver class name
57
* @param properties driver properties
58
* @param username database username
59
* @param password database password
60
*/
61
public DriverDataSource(String jdbcUrl, String driverClassName,
62
Properties properties, String username, String password);
63
64
/**
65
* Get connection using configured credentials.
66
*
67
* @return new database connection
68
* @throws SQLException on connection error
69
*/
70
public Connection getConnection() throws SQLException;
71
72
/**
73
* Get connection (ignores username/password parameters).
74
*
75
* @param username ignored
76
* @param password ignored
77
* @return new database connection
78
* @throws SQLException on connection error
79
*/
80
public Connection getConnection(String username, String password) throws SQLException;
81
82
/**
83
* Get log writer (throws SQLFeatureNotSupportedException).
84
*
85
* @return never returns normally
86
* @throws SQLException always thrown
87
*/
88
public PrintWriter getLogWriter() throws SQLException;
89
90
/**
91
* Set log writer (throws SQLFeatureNotSupportedException).
92
*
93
* @param logWriter ignored
94
* @throws SQLException always thrown
95
*/
96
public void setLogWriter(PrintWriter logWriter) throws SQLException;
97
98
/**
99
* Set login timeout in seconds.
100
*
101
* @param seconds timeout in seconds
102
* @throws SQLException on error
103
*/
104
public void setLoginTimeout(int seconds) throws SQLException;
105
106
/**
107
* Get login timeout in seconds.
108
*
109
* @return timeout in seconds
110
* @throws SQLException on error
111
*/
112
public int getLoginTimeout() throws SQLException;
113
114
/**
115
* Get parent logger.
116
*
117
* @return parent logger
118
* @throws SQLFeatureNotSupportedException if not supported
119
*/
120
public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException;
121
122
/**
123
* Unwrap to specified interface (throws SQLFeatureNotSupportedException).
124
*
125
* @param iface target interface
126
* @return never returns normally
127
* @throws SQLException always thrown
128
*/
129
public <T> T unwrap(Class<T> iface) throws SQLException;
130
131
/**
132
* Check if wrapper for interface (always returns false).
133
*
134
* @param iface target interface
135
* @return false
136
* @throws SQLException on error
137
*/
138
public boolean isWrapperFor(Class<?> iface) throws SQLException;
139
140
/**
141
* Shutdown the DataSource (no-op implementation).
142
*/
143
public void shutdown();
144
}
145
```
146
147
### High-Performance Collections
148
149
Specialized collections optimized for HikariCP's internal use.
150
151
```java { .api }
152
public class FastList<T> {
153
/**
154
* Create FastList with default capacity (32).
155
*
156
* @param clazz element class for array creation
157
*/
158
public FastList(Class<?> clazz);
159
160
/**
161
* Create FastList with specified capacity.
162
*
163
* @param clazz element class for array creation
164
* @param capacity initial capacity
165
*/
166
public FastList(Class<?> clazz, int capacity);
167
168
/**
169
* Add element to the end of the list.
170
* No bounds checking for performance.
171
*
172
* @param element element to add
173
*/
174
public void add(T element);
175
176
/**
177
* Get element at specified index.
178
* No bounds checking for performance.
179
*
180
* @param index element index
181
* @return element at index
182
*/
183
public T get(int index);
184
185
/**
186
* Remove and return the last element.
187
*
188
* @return last element
189
*/
190
public T removeLast();
191
192
/**
193
* Remove specified element using identity comparison.
194
*
195
* @param element element to remove
196
*/
197
public void remove(T element);
198
199
/**
200
* Clear all elements from the list.
201
*/
202
public void clear();
203
204
/**
205
* Get current number of elements.
206
*
207
* @return current size
208
*/
209
public int size();
210
}
211
```
212
213
### Concurrent Collections
214
215
Lock-free concurrent collection used internally by HikariCP for optimal performance.
216
217
```java { .api }
218
public class ConcurrentBag<T extends IConcurrentBagEntry> {
219
// Lock-free concurrent collection for connection pooling
220
// Optimized for high-performance access patterns
221
}
222
223
public interface IConcurrentBagEntry {
224
// Interface for objects stored in ConcurrentBag
225
// Provides state management for pooled connections
226
}
227
228
public interface IBagStateListener {
229
// Listener interface for ConcurrentBag state changes
230
// Used for pool management notifications
231
}
232
```
233
234
### Thread Management
235
236
Default thread factory implementation for HikariCP thread pools.
237
238
```java { .api }
239
public class DefaultThreadFactory implements ThreadFactory {
240
// Creates daemon threads for HikariCP internal operations
241
// Provides proper naming and exception handling
242
}
243
```
244
245
### Property Management
246
247
Utility for setting Java Bean properties from Properties objects.
248
249
```java { .api }
250
public class PropertyBeanSetter {
251
// Utility for reflective property setting
252
// Handles type conversion and bean property mapping
253
}
254
```
255
256
### General Utilities
257
258
Collection of utility methods used throughout HikariCP.
259
260
```java { .api }
261
public class UtilityElf {
262
// General utility methods for:
263
// - String manipulation
264
// - Numeric operations
265
// - Validation helpers
266
// - System property access
267
}
268
```
269
270
### Class Loading Utilities
271
272
Utilities for dynamic class loading and reflection operations.
273
274
```java { .api }
275
public class ClassLoaderUtils {
276
// Class loading utilities for:
277
// - Dynamic driver loading
278
// - Reflection operations
279
// - Classpath management
280
}
281
```
282
283
284
### Exception Types
285
286
Specific exception types used by HikariCP.
287
288
```java { .api }
289
public class PoolInitializationException extends RuntimeException {
290
/**
291
* Construct with cause.
292
*
293
* @param t underlying cause of initialization failure
294
*/
295
public PoolInitializationException(Throwable t);
296
}
297
```
298
299
## Usage Examples
300
301
### JNDI Configuration
302
303
#### Application Server Deployment
304
305
```xml
306
<!-- In server.xml or equivalent for JNDI deployment -->
307
<Resource name="jdbc/MyDataSource"
308
auth="Container"
309
factory="com.zaxxer.hikari.HikariJNDIFactory"
310
type="javax.sql.DataSource"
311
jdbcUrl="jdbc:postgresql://localhost/mydb"
312
username="dbuser"
313
password="dbpass"
314
maximumPoolSize="20"
315
minimumIdle="5"
316
connectionTimeout="30000"
317
idleTimeout="600000"
318
poolName="JNDIPool" />
319
```
320
321
#### JNDI Lookup
322
323
```java
324
import javax.naming.Context;
325
import javax.naming.InitialContext;
326
import javax.sql.DataSource;
327
328
// Lookup DataSource from JNDI
329
Context ctx = new InitialContext();
330
DataSource dataSource = (DataSource) ctx.lookup("jdbc/MyDataSource");
331
332
// Use the DataSource normally
333
try (Connection conn = dataSource.getConnection()) {
334
// Database operations
335
}
336
```
337
338
### Custom Connection Handling
339
340
#### Using DriverDataSource Directly
341
342
```java
343
import com.zaxxer.hikari.util.DriverDataSource;
344
import java.util.Properties;
345
346
// Create properties for driver configuration
347
Properties driverProps = new Properties();
348
driverProps.setProperty("useSSL", "false");
349
driverProps.setProperty("serverTimezone", "UTC");
350
driverProps.setProperty("cachePrepStmts", "true");
351
352
// Create DriverDataSource
353
DriverDataSource driverDataSource = new DriverDataSource(
354
"jdbc:mysql://localhost:3306/mydb",
355
"com.mysql.jdbc.Driver",
356
driverProps,
357
"user",
358
"password"
359
);
360
361
// Use directly or wrap with HikariCP
362
HikariConfig config = new HikariConfig();
363
config.setDataSource(driverDataSource);
364
config.setMaximumPoolSize(10);
365
366
HikariDataSource pooledDataSource = new HikariDataSource(config);
367
```
368
369
#### Legacy Connection Customizer (Deprecated)
370
371
```java
372
import com.zaxxer.hikari.IConnectionCustomizer;
373
import java.sql.Connection;
374
import java.sql.SQLException;
375
import java.sql.Statement;
376
377
// Custom connection customizer (deprecated - use connectionInitSql instead)
378
public class MyConnectionCustomizer implements IConnectionCustomizer {
379
@Override
380
public void customize(Connection connection) throws SQLException {
381
try (Statement stmt = connection.createStatement()) {
382
// Set session variables
383
stmt.execute("SET SESSION sql_mode = 'STRICT_TRANS_TABLES'");
384
stmt.execute("SET SESSION time_zone = '+00:00'");
385
}
386
}
387
}
388
389
// Configure with customizer (deprecated approach)
390
HikariConfig config = new HikariConfig();
391
config.setConnectionCustomizer(new MyConnectionCustomizer());
392
393
// Modern approach - use connectionInitSql instead
394
HikariConfig modernConfig = new HikariConfig();
395
modernConfig.setConnectionInitSql(
396
"SET SESSION sql_mode = 'STRICT_TRANS_TABLES'; " +
397
"SET SESSION time_zone = '+00:00';"
398
);
399
```
400
401
### Advanced Proxy Usage
402
403
#### Accessing Pool Information from Connection
404
405
```java
406
import com.zaxxer.hikari.proxy.IHikariConnectionProxy;
407
408
// Get connection from HikariCP
409
try (Connection conn = dataSource.getConnection()) {
410
// Cast to HikariCP proxy interface
411
if (conn instanceof IHikariConnectionProxy) {
412
IHikariConnectionProxy hikariConn = (IHikariConnectionProxy) conn;
413
414
// Access pool-specific information
415
PoolBagEntry bagEntry = hikariConn.getPoolBagEntry();
416
System.out.println("Connection created at: " + bagEntry.getCreationTime());
417
System.out.println("Last accessed: " + bagEntry.getLastAccess());
418
419
// The proxy automatically handles:
420
// - Statement tracking and cleanup
421
// - Connection state management
422
// - Leak detection
423
// - Exception analysis for connection validity
424
}
425
426
// Use connection normally - proxy behavior is transparent
427
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM users WHERE id = ?");
428
stmt.setInt(1, 123);
429
ResultSet rs = stmt.executeQuery();
430
// ResultSet and Statement are also proxied automatically
431
}
432
```
433
434
### High-Performance Collections Usage
435
436
#### FastList for Custom Applications
437
438
```java
439
import com.zaxxer.hikari.util.FastList;
440
441
// Create high-performance list for connection objects
442
FastList<Connection> connectionList = new FastList<>(Connection.class, 10);
443
444
// Add connections (no bounds checking for performance)
445
connectionList.add(connection1);
446
connectionList.add(connection2);
447
connectionList.add(connection3);
448
449
// Access by index (no bounds checking)
450
Connection firstConn = connectionList.get(0);
451
452
// Remove last connection efficiently
453
Connection lastConn = connectionList.removeLast();
454
455
// Remove specific connection by identity
456
connectionList.remove(connection2);
457
458
// Get current size
459
int size = connectionList.size();
460
461
// Clear all connections
462
connectionList.clear();
463
```
464
465
### Custom Thread Factory
466
467
```java
468
import com.zaxxer.hikari.util.DefaultThreadFactory;
469
import java.util.concurrent.ThreadFactory;
470
471
// Use HikariCP's default thread factory for consistency
472
ThreadFactory hikariThreadFactory = new DefaultThreadFactory();
473
474
// Configure HikariCP with custom thread factory
475
HikariConfig config = new HikariConfig();
476
config.setJdbcUrl("jdbc:postgresql://localhost/mydb");
477
config.setUsername("user");
478
config.setPassword("password");
479
config.setThreadFactory(hikariThreadFactory);
480
481
// Or create custom thread factory following HikariCP patterns
482
ThreadFactory customFactory = new ThreadFactory() {
483
private int counter = 0;
484
485
@Override
486
public Thread newThread(Runnable r) {
487
Thread thread = new Thread(r, "MyApp-HikariCP-" + (++counter));
488
thread.setDaemon(true); // Important: make daemon threads
489
thread.setUncaughtExceptionHandler((t, e) -> {
490
System.err.println("Uncaught exception in thread " + t.getName() + ": " + e.getMessage());
491
});
492
return thread;
493
}
494
};
495
496
config.setThreadFactory(customFactory);
497
```
498
499
### Property Bean Configuration
500
501
```java
502
import com.zaxxer.hikari.util.PropertyBeanSetter;
503
import java.util.Properties;
504
505
// Example of using PropertyBeanSetter for custom configuration objects
506
public class MyDatabaseConfig {
507
private String host;
508
private int port;
509
private boolean useSSL;
510
511
// Getters and setters...
512
public void setHost(String host) { this.host = host; }
513
public void setPort(int port) { this.port = port; }
514
public void setUseSSL(boolean useSSL) { this.useSSL = useSSL; }
515
}
516
517
// Configure from properties
518
Properties props = new Properties();
519
props.setProperty("host", "localhost");
520
props.setProperty("port", "5432");
521
props.setProperty("useSSL", "true");
522
523
MyDatabaseConfig config = new MyDatabaseConfig();
524
PropertyBeanSetter.setTargetFromProperties(config, props);
525
```
526
527
### Exception Handling
528
529
```java
530
import com.zaxxer.hikari.pool.PoolInitializationException;
531
532
try {
533
HikariConfig config = new HikariConfig();
534
config.setJdbcUrl("jdbc:invalid://invalid");
535
config.setInitializationFailFast(true); // Fail fast on invalid config
536
537
HikariDataSource dataSource = new HikariDataSource(config);
538
} catch (PoolInitializationException e) {
539
System.err.println("Pool initialization failed: " + e.getMessage());
540
Throwable cause = e.getCause();
541
if (cause != null) {
542
System.err.println("Root cause: " + cause.getMessage());
543
}
544
545
// Handle initialization failure appropriately
546
// - Log error details
547
// - Use fallback DataSource
548
// - Retry with different configuration
549
// - Fail application startup
550
}
551
```
552
553
### Integration with Custom Monitoring
554
555
```java
556
import com.zaxxer.hikari.proxy.IHikariConnectionProxy;
557
558
// Custom connection monitoring
559
public class ConnectionMonitor {
560
public static void monitorConnection(Connection conn) {
561
if (conn instanceof IHikariConnectionProxy) {
562
IHikariConnectionProxy proxy = (IHikariConnectionProxy) conn;
563
PoolBagEntry entry = proxy.getPoolBagEntry();
564
565
// Log connection usage
566
long ageMs = System.currentTimeMillis() - entry.getCreationTime();
567
System.out.println("Using connection age: " + ageMs + "ms");
568
569
// Track connection in custom metrics
570
MyMetrics.recordConnectionAge(ageMs);
571
MyMetrics.incrementActiveConnections();
572
}
573
}
574
}
575
576
// Use in application
577
try (Connection conn = dataSource.getConnection()) {
578
ConnectionMonitor.monitorConnection(conn);
579
580
// Database operations
581
// ...
582
583
} // Connection automatically returned to pool with cleanup
584
```