This document covers configuration options for the OJP JDBC driver, including client-side connection pool settings with multi-datasource support.
The OJP JDBC driver supports configurable connection pool settings via an ojp.properties file with advanced multi-datasource capabilities. This allows customization of HikariCP connection pool behavior on a per-client basis with support for multiple named datasources for enhanced flexibility.
The multi-datasource configuration approach provides several operational benefits:
- Configuration Isolation: Different applications or components can have their own pool configurations without interfering with each other
- Operational Flexibility: Different datasources can point to the same database with different pool settings optimized for their use case
- Resource Management: Fine-grained control over connection pool resources per application component
Configure pool settings for specific datasources using the format {dataSourceName}.ojp.connection.pool.*:
# Main application datasource - high concurrency
mainApp.ojp.connection.pool.maximumPoolSize=50
mainApp.ojp.connection.pool.minimumIdle=10
mainApp.ojp.connection.pool.connectionTimeout=15000
# Read-only reporting datasource - smaller pool
reporting.ojp.connection.pool.maximumPoolSize=8
reporting.ojp.connection.pool.minimumIdle=2
reporting.ojp.connection.pool.idleTimeout=300000
# Batch processing datasource - medium pool with longer timeouts
batchJob.ojp.connection.pool.maximumPoolSize=15
batchJob.ojp.connection.pool.minimumIdle=3
batchJob.ojp.connection.pool.maxLifetime=1800000For backward compatibility, properties without a datasource prefix are treated as the "default" datasource:
# Default datasource configuration (backward compatible)
ojp.connection.pool.maximumPoolSize=20
ojp.connection.pool.minimumIdle=5
ojp.connection.pool.idleTimeout=600000# Default Maximum Inbound Message Size Configuration
ojp.grpc.maxInboundMessageSize=16777216 Include the dataSource name in parentheses within the OJP connection section to specify which datasource configuration to use:
// Use the mainApp datasource configuration
String url = "jdbc:ojp[localhost:1059(mainApp)]_postgresql://user@localhost/mydb";
Connection conn = DriverManager.getConnection(url, "user", "password");
// Use the reporting datasource configuration
String reportingUrl = "jdbc:ojp[localhost:1059(reporting)]_postgresql://user@localhost/mydb";
Connection reportingConn = DriverManager.getConnection(reportingUrl, "user", "password");
// Use default configuration (no dataSource parameter)
String defaultUrl = "jdbc:ojp[localhost:1059]_postgresql://user@localhost/mydb";
Connection defaultConn = DriverManager.getConnection(defaultUrl, "user", "password");Multiple datasources can point to the same database connection parameters while using different pool configurations:
# Primary application pool - high capacity
primary.ojp.connection.pool.maximumPoolSize=40
primary.ojp.connection.pool.minimumIdle=8
# Background tasks pool - smaller capacity
background.ojp.connection.pool.maximumPoolSize=10
background.ojp.connection.pool.minimumIdle=2Both can connect to the same database:
// Same database, different pool configurations
Connection primaryConn = DriverManager.getConnection(
"jdbc:ojp[localhost:1059(primary)]_postgres:mydb", "user", "pass");
Connection backgroundConn = DriverManager.getConnection(
"jdbc:ojp[localhost:1059(background)]_postgres:mydb", "user", "pass");- Create an
ojp.propertiesfile in your application's classpath (either in the root or in theresourcesfolder) - Add any of the supported properties (all are optional)
- Use either named datasource configuration or default configuration format
- The driver will automatically load and send these properties to the server when establishing a connection
OJP supports environment-specific properties files, allowing you to maintain separate configurations for different environments (development, staging, production, etc.) without requiring any custom code.
Use the following naming pattern for environment-specific properties files:
ojp-dev.properties- Development environmentojp-staging.properties- Staging environmentojp-prod.properties- Production environmentojp-test.properties- Testing environmentojp-{environment}.properties- Any custom environment name
The environment is automatically determined by (in order of precedence):
- System property:
-Dojp.environment=dev - Environment variable:
OJP_ENVIRONMENT=dev
If no environment is specified, OJP loads the default ojp.properties file.
- If an environment is specified but the environment-specific file doesn't exist, OJP automatically falls back to
ojp.properties - This ensures backward compatibility and provides a safe default configuration
Development Environment (ojp-dev.properties):
# Development configuration - smaller pools, more logging
ojp.connection.pool.maximumPoolSize=10
ojp.connection.pool.minimumIdle=2
ojp.connection.pool.connectionTimeout=30000
ojp.connection.pool.idleTimeout=300000
# XA settings for development
ojp.xa.connection.pool.maxTotal=5
ojp.xa.connection.pool.minIdle=1Staging Environment (ojp-staging.properties):
# Staging configuration - moderate pools, production-like
ojp.connection.pool.maximumPoolSize=20
ojp.connection.pool.minimumIdle=5
ojp.connection.pool.connectionTimeout=20000
ojp.connection.pool.idleTimeout=600000
# XA settings for staging
ojp.xa.connection.pool.maxTotal=15
ojp.xa.connection.pool.minIdle=3Production Environment (ojp-prod.properties):
# Production configuration - optimized for high load
ojp.connection.pool.maximumPoolSize=50
ojp.connection.pool.minimumIdle=10
ojp.connection.pool.connectionTimeout=15000
ojp.connection.pool.idleTimeout=600000
ojp.connection.pool.maxLifetime=1800000
# XA settings for production
ojp.xa.connection.pool.maxTotal=40
ojp.xa.connection.pool.minIdle=8
ojp.xa.connection.pool.connectionTimeout=25000
# Production-specific datasources
webapp.ojp.connection.pool.maximumPoolSize=60
webapp.ojp.connection.pool.minimumIdle=15
api.ojp.connection.pool.maximumPoolSize=40
api.ojp.connection.pool.minimumIdle=10Using System Property:
# Development
java -Dojp.environment=dev -jar myapp.jar
# Staging
java -Dojp.environment=staging -jar myapp.jar
# Production
java -Dojp.environment=prod -jar myapp.jarUsing Environment Variable:
# Development
export OJP_ENVIRONMENT=dev
java -jar myapp.jar
# Staging
export OJP_ENVIRONMENT=staging
java -jar myapp.jar
# Production
export OJP_ENVIRONMENT=prod
java -jar myapp.jarDocker Deployment:
# docker-compose.yml
services:
app-dev:
image: myapp:latest
environment:
- OJP_ENVIRONMENT=dev
app-prod:
image: myapp:latest
environment:
- OJP_ENVIRONMENT=prodKubernetes Deployment:
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
template:
spec:
containers:
- name: myapp
image: myapp:latest
env:
- name: OJP_ENVIRONMENT
value: "prod"- No Custom Code Required: Simply specify the environment and OJP automatically loads the correct configuration
- Single Application Package: Deploy the same JAR/WAR to all environments with all configuration files included
- Clear Separation: Each environment has its own clearly named configuration file
- Easy Testing: Test different environment configurations locally by changing the environment variable
- Safe Defaults: Falls back to
ojp.propertiesif environment-specific file is missing - Override Support: Environment variables and system properties can still override file properties
Complete example configuration files for different environments are available:
- ojp-dev.properties - Development environment configuration
- ojp-staging.properties - Staging environment configuration
- ojp-prod.properties - Production environment configuration
These examples demonstrate recommended settings for each environment and can be used as starting templates.
| Property | Type | Default | Description | Since |
|---|---|---|---|---|
ojp.connection.pool.enabled |
boolean | true | Enable/disable connection pooling | 0.2.0-beta |
ojp.connection.pool.maximumPoolSize |
int | 20 | Maximum number of connections in the pool | 0.2.0-beta |
ojp.connection.pool.minimumIdle |
int | 5 | Minimum number of idle connections maintained | 0.2.0-beta |
ojp.connection.pool.idleTimeout |
long | 600000 | Maximum time (ms) a connection can sit idle (10 minutes) | 0.2.0-beta |
ojp.connection.pool.maxLifetime |
long | 1800000 | Maximum lifetime (ms) of a connection (30 minutes) | 0.2.0-beta |
ojp.connection.pool.connectionTimeout |
long | 10000 | Maximum time (ms) to wait for a connection (10 seconds) | 0.2.0-beta |
ojp.connection.pool.defaultTransactionIsolation |
string/int | READ_COMMITTED | Default transaction isolation level (see below) | 0.2.0-beta |
Note: These properties can be used with or without a datasource name prefix. For example:
ojp.connection.pool.maximumPoolSize=20(default datasource)myApp.ojp.connection.pool.maximumPoolSize=50(myApp datasource)
OJP automatically resets transaction isolation levels when connections are returned to the pool, preventing state pollution between different client sessions.
By default, OJP uses READ_COMMITTED as the default transaction isolation level. You can override this by explicitly configuring a different isolation level.
| Property | Type | Default | Description | Since |
|---|---|---|---|---|
ojp.connection.pool.defaultTransactionIsolation |
string/int | READ_COMMITTED | Transaction isolation level to reset connections to | 0.2.0-beta |
ojp.xa.connection.pool.defaultTransactionIsolation |
string/int | READ_COMMITTED | Transaction isolation level for XA connections | 0.2.0-beta |
The property accepts multiple formats (case-insensitive):
| String Name | Constant Name | Description |
|---|---|---|
NONE |
TRANSACTION_NONE |
Transactions not supported |
READ_UNCOMMITTED |
TRANSACTION_READ_UNCOMMITTED |
Lowest isolation - dirty reads allowed |
READ_COMMITTED |
TRANSACTION_READ_COMMITTED |
Most common - prevents dirty reads |
REPEATABLE_READ |
TRANSACTION_REPEATABLE_READ |
Prevents non-repeatable reads |
SERIALIZABLE |
TRANSACTION_SERIALIZABLE |
Highest isolation - fully isolated |
# Using string name (recommended - most readable)
ojp.connection.pool.defaultTransactionIsolation=READ_COMMITTED
# Using constant name
ojp.connection.pool.defaultTransactionIsolation=TRANSACTION_SERIALIZABLE
# For XA connections
ojp.xa.connection.pool.defaultTransactionIsolation=SERIALIZABLE
# Per-datasource configuration
mainApp.ojp.connection.pool.defaultTransactionIsolation=SERIALIZABLE
reporting.ojp.connection.pool.defaultTransactionIsolation=READ_COMMITTEDConfigure a custom isolation level when:
- You want all connections to use a specific isolation level regardless of database default
- Different applications sharing the same database need different isolation guarantees
- You want to enforce a stricter or more relaxed isolation policy
- Default (READ_COMMITTED): OJP uses READ_COMMITTED isolation level by default for all connections
- Configured: When set, OJP uses the specified isolation level instead of the default
- Connection Reset: When connections return to the pool, they are automatically reset to the configured isolation level (or READ_COMMITTED if not configured)
- Optimization: The connection pool only resets isolation if it was actually changed during the session
Note: See documents/analysis/TRANSACTION_ISOLATION_HANDLING.md for complete technical documentation.
Both Non-XA and XA connection pooling can be disabled independently using configuration properties. This is useful for:
- Development and Testing: Simplify debugging by removing pool complexity
- Low-Frequency Applications: When connection reuse overhead exceeds benefits
- Diagnostic Mode: Isolate issues related to connection pooling
- Single-Threaded Applications: Where connection pooling provides no benefit
Disable Non-XA connection pooling using:
# Disable pooling for default datasource
ojp.connection.pool.enabled=false
# Disable pooling for specific datasource
myApp.ojp.connection.pool.enabled=falseConfiguration Precedence:
Properties can be specified in three ways, with the following precedence (highest to lowest):
-
Environment Variables (highest priority)
# Disable pooling via environment variable export MYAPP_OJP_CONNECTION_POOL_ENABLED=false export OJP_CONNECTION_POOL_ENABLED=false # for default datasource
-
System Properties (via
-Dflags)# Disable pooling via system property java -Dmyapp.ojp.connection.pool.enabled=false -jar app.jar mvn test -Dmultinode.ojp.connection.pool.enabled=false
-
Properties File (
ojp.properties- lowest priority)myapp.ojp.connection.pool.enabled=false
Behavior when disabled:
- Connections created directly via
DriverManager.getConnection() - No connection reuse - new connection per request
- Lower memory overhead, higher connection acquisition latency
- Pool size properties (maximumPoolSize, minimumIdle) are ignored
Example Configuration:
# Debugging datasource with pool disabled
debug.ojp.connection.pool.enabled=false
debug.ojp.connection.pool.connectionTimeout=5000
# Production datasource with pool enabled
prod.ojp.connection.pool.enabled=true
prod.ojp.connection.pool.maximumPoolSize=50
prod.ojp.connection.pool.minimumIdle=10Disable XA connection pooling using:
# Disable XA pooling for default datasource
ojp.xa.connection.pool.enabled=false
# Disable XA pooling for specific datasource
myApp.ojp.xa.connection.pool.enabled=falseConfiguration Precedence:
Properties can be specified in three ways, with the following precedence (highest to lowest):
-
Environment Variables (highest priority)
# Disable XA pooling via environment variable export MYAPP_OJP_XA_CONNECTION_POOL_ENABLED=false export OJP_XA_CONNECTION_POOL_ENABLED=false # for default datasource
-
System Properties (via
-Dflags)# Disable XA pooling via system property java -Dmyapp.ojp.xa.connection.pool.enabled=false -jar app.jar mvn test -Dmultinode.ojp.xa.connection.pool.enabled=false
-
Properties File (
ojp.properties- lowest priority)myapp.ojp.xa.connection.pool.enabled=false
Behavior when disabled:
- XADataSource created directly without pooling
- XAConnections created on demand per session
- No backend session pooling - direct XA operations
- Lower overhead for infrequent XA transactions
- Pool size properties (maxTotal, minIdle) are ignored
Example Configuration:
# Testing XA datasource with pool disabled
test.ojp.xa.connection.pool.enabled=false
# Production XA datasource with pool enabled
prod.ojp.xa.connection.pool.enabled=true
prod.ojp.xa.connection.pool.maxTotal=50
prod.ojp.xa.connection.pool.minIdle=10Important Notes:
- Non-XA and XA pool settings are independent - you can disable one without affecting the other
- When pooling is disabled, connection acquisition is slower but simpler
- Pool disable is applied per datasource name, allowing mixed configurations
- For production workloads with high concurrency, keeping pooling enabled is recommended
When using XA (distributed transaction) connections via OjpXADataSource with pooling enabled, OJP uses server-side backend session pooling with Apache Commons Pool 2. This is separate from the HikariCP pooling used for non-XA connections.
| Property | Type | Default | Description | Since |
|---|---|---|---|---|
ojp.xa.connection.pool.enabled |
boolean | true | Enable/disable XA connection pooling | 0.2.0-beta |
ojp.xa.connection.pool.maxTotal |
int | 20 | Maximum XA backend sessions per server | 0.2.0-beta |
ojp.xa.connection.pool.minIdle |
int | 5 | Minimum idle XA sessions (pre-warmed) | 0.2.0-beta |
ojp.xa.connection.pool.connectionTimeout |
long | 20000 | Max wait time (ms) to borrow session (20 seconds) | 0.2.0-beta |
ojp.xa.connection.pool.idleTimeout |
long | 600000 | Max idle time (ms) before eviction (10 minutes) | 0.2.0-beta |
ojp.xa.connection.pool.maxLifetime |
long | 1800000 | Max lifetime (ms) of XA session (30 minutes) | 0.2.0-beta |
ojp.xa.connection.pool.timeBetweenEvictionRuns |
long | 30000 | How often evictor runs (ms) to clean up excess idle connections (30 seconds) | 0.2.0-beta |
ojp.xa.connection.pool.numTestsPerEvictionRun |
int | 10 | Number of idle connections checked per eviction run | 0.2.0-beta |
ojp.xa.connection.pool.softMinEvictableIdleTime |
long | 60000 | Min idle time (ms) before soft eviction respecting minIdle (60 seconds) | 0.2.0-beta |
- Client Side: No connection pooling - connections created and closed after use (when XA pooling enabled)
- Client Side (pooling disabled): XAConnections created on demand without any pooling
- Server Side: Apache Commons Pool 2 pools PostgreSQL XA backend sessions
- Connection Reuse: Physical XAConnection stays open across multiple transactions
- Dual-Condition Lifecycle: Sessions returned to pool only when BOTH transaction complete AND client XAConnection closed
Note: These are configuration examples only, not recommendations. Adjust pool sizes based on your application's actual workload characteristics and resource constraints.
# Default XA backend session pool
ojp.xa.connection.pool.maxTotal=20
ojp.xa.connection.pool.minIdle=5
ojp.xa.connection.pool.connectionTimeout=20000
# High-volume application with more XA concurrency
mainApp.ojp.xa.connection.pool.maxTotal=100
mainApp.ojp.xa.connection.pool.minIdle=10
mainApp.ojp.xa.connection.pool.connectionTimeout=30000
# Analytics with lower XA concurrency
analytics.ojp.xa.connection.pool.maxTotal=25
analytics.ojp.xa.connection.pool.minIdle=3
analytics.ojp.xa.connection.pool.connectionTimeout=15000For N servers with maxTotal=M:
- Each server gets: M / N sessions
- Example: 2 servers, maxTotal=22 → 11 per server
- Automatic rebalancing on server failures/recoveries
Enable DEBUG logging for pool diagnostics:
-Dorg.slf4j.simpleLogger.log.org.openjproxy=DEBUGLog output includes:
XA pool initialized: server=localhost:5432, maxTotal=11, minIdle=10
Session borrowed successfully: poolState=[active=2, idle=8, maxTotal=11]
Session returned to pool: poolState=[active=1, idle=9, maxTotal=11]
Pool resized due to cluster health change: maxTotal=11→22, minIdle=10→20
For comprehensive XA management documentation, see XA Management Guide
# Multi-datasource configuration example
# Default datasource for backward compatibility
ojp.connection.pool.maximumPoolSize=25
ojp.connection.pool.minimumIdle=5
ojp.connection.pool.idleTimeout=300000
ojp.connection.pool.maxLifetime=900000
ojp.connection.pool.connectionTimeout=15000
# XA backend session pool (server-side)
ojp.xa.connection.pool.maxTotal=20
ojp.xa.connection.pool.minIdle=5
ojp.xa.connection.pool.connectionTimeout=20000
ojp.xa.connection.pool.idleTimeout=600000
ojp.xa.connection.pool.maxLifetime=1800000
ojp.xa.connection.pool.timeBetweenEvictionRuns=30000
ojp.xa.connection.pool.numTestsPerEvictionRun=10
ojp.xa.connection.pool.softMinEvictableIdleTime=60000
# High-performance application datasource
webapp.ojp.connection.pool.maximumPoolSize=50
webapp.ojp.connection.pool.minimumIdle=10
webapp.ojp.connection.pool.connectionTimeout=5000
webapp.ojp.xa.connection.pool.maxTotal=100
webapp.ojp.xa.connection.pool.minIdle=10
webapp.ojp.xa.connection.pool.connectionTimeout=30000
# Batch processing datasource
batch.ojp.connection.pool.maximumPoolSize=20
batch.ojp.connection.pool.minimumIdle=2
batch.ojp.connection.pool.maxLifetime=3600000
batch.ojp.xa.connection.pool.maxTotal=22
batch.ojp.xa.connection.pool.minIdle=15
batch.ojp.xa.connection.pool.connectionTimeout=25000
# Read-only analytics datasource
analytics.ojp.connection.pool.maximumPoolSize=8
analytics.ojp.connection.pool.minimumIdle=1
analytics.ojp.connection.pool.idleTimeout=900000
analytics.ojp.xa.connection.pool.maxTotal=11
analytics.ojp.xa.connection.pool.minIdle=5
analytics.ojp.xa.connection.pool.connectionTimeout=15000- If no
ojp.propertiesfile is found, all default values are used - If a property is missing from the file, its default value is used
- If a property has an invalid value, the default is used and a warning is logged
- If a datasource name is not configured, the connection will use server defaults
- All validation and configuration logic is handled on the server side
- Use descriptive datasource names that reflect their purpose (e.g.,
webApp,batchJob,analytics) - Size pools appropriately for each use case - high-traffic web applications need larger pools than batch jobs
- Configure timeouts based on expected connection usage patterns
- Monitor pool metrics using JMX to optimize settings over time
- Use smaller pools for background tasks to prevent resource exhaustion
Add the OJP JDBC driver dependency to your project:
<dependency>
<groupId>org.openjproxy</groupId>
<artifactId>ojp-jdbc-driver</artifactId>
<version>0.4.0-beta</version>
</dependency>Replace your existing JDBC connection URL by prefixing with ojp[host:port]_ and optionally specify a datasource:
// Before (PostgreSQL example)
"jdbc:postgresql://user@localhost/mydb"
// After with default datasource
"jdbc:ojp[localhost:1059]_postgresql://user@localhost/mydb"
// After with named datasource
"jdbc:ojp[localhost:1059(mainApp)]_postgresql://user@localhost/mydb"
// Oracle example with datasource
"jdbc:ojp[localhost:1059(analytics)]_oracle:thin:@localhost:1521/XEPDB1"
// SQL Server example with datasource
"jdbc:ojp[localhost:1059(reporting)]_sqlserver://localhost:1433;databaseName=mydb"Use the OJP driver class: org.openjproxy.jdbc.Driver
OJP supports server-side SSL/TLS certificate configuration using property placeholders in JDBC URLs. This allows certificate paths to be configured on the OJP server rather than hardcoded in the client connection URL.
- Centralized certificate management: Certificates reside on the OJP server
- Security: Certificate paths are not exposed in application configuration
- Environment flexibility: Different certificate paths for dev/staging/production
- Simplified client configuration: Clients don't need access to certificate files
Step 1: Configure the JDBC URL with placeholders in ojp.properties:
# PostgreSQL with SSL
mainApp.ojp.datasource.url=jdbc:ojp[localhost:1059(mainApp)]_postgresql://dbhost:5432/mydb?ssl=true&sslmode=verify-full&sslrootcert=${ojp.server.sslrootcert}
# MySQL with SSL
reporting.ojp.datasource.url=jdbc:ojp[localhost:1059(reporting)]_mysql://dbhost:3306/mydb?useSSL=true&trustCertificateKeyStoreUrl=${ojp.server.mysql.truststore}
# Oracle with wallet
analytics.ojp.datasource.url=jdbc:ojp[localhost:1059(analytics)]_oracle:thin:@dbhost:2484/myservice?oracle.net.wallet_location=${ojp.server.oracle.wallet.location}Step 2: Configure the certificate paths on the OJP server (see OJP Server Configuration):
# Using JVM properties
java -Duser.timezone=UTC \
-jar ojp-server.jar \
-Dojp.server.sslrootcert=/etc/ojp/certs/ca-cert.pem \
-Dojp.server.mysql.truststore=file:///etc/ojp/certs/truststore.jks \
-Dojp.server.oracle.wallet.location=/etc/ojp/wallet
# Or using environment variables
export OJP_SERVER_SSLROOTCERT=/etc/ojp/certs/ca-cert.pem
export OJP_SERVER_MYSQL_TRUSTSTORE=file:///etc/ojp/certs/truststore.jks
export OJP_SERVER_ORACLE_WALLET_LOCATION=/etc/ojp/walletPlaceholders use the format: ${property.name}
Security Note: Property names are validated on the server to prevent attacks if a client is compromised. Only property names starting with ojp.server. or ojp.client. are allowed, and they must contain only alphanumeric characters, dots, hyphens, and underscores.
Naming convention:
- Always use the ojp.server prefix:
${ojp.server.sslrootcert}(required for validation) - Use descriptive names:
${ojp.server.postgresql.sslrootcert}is better than${cert1} - Include database type:
${ojp.server.mysql.truststore},${ojp.server.db2.keystore} - Include environment if needed:
${ojp.server.prod.sslrootcert} - Use only allowed characters: alphanumeric, dots (
.), hyphens (-), underscores (_) - Keep suffix under 200 characters
Why these rules matter: If a client application is compromised, attackers could inject malicious property names. The validation rules prevent:
- Access to system properties like
${java.home} - Command injection through special characters like
;,|,& - Path traversal attacks like
../../../etc/passwd - SQL injection attempts
- Denial of service through extremely long names
For complete security details, see the SSL/TLS Certificate Configuration Guide.
PostgreSQL:
ojp.datasource.url=jdbc:ojp[localhost:1059]_postgresql://host:5432/db?\
ssl=true&sslmode=verify-full&\
sslrootcert=${ojp.server.sslrootcert}&\
sslcert=${ojp.server.sslcert}&\
sslkey=${ojp.server.sslkey}MySQL/MariaDB:
ojp.datasource.url=jdbc:ojp[localhost:1059]_mysql://host:3306/db?\
useSSL=true&requireSSL=true&\
trustCertificateKeyStoreUrl=${ojp.server.mysql.truststore}&\
trustCertificateKeyStorePassword=${ojp.server.mysql.truststorePassword}Oracle:
ojp.datasource.url=jdbc:ojp[localhost:1059]_oracle:thin:@host:2484/service?\
oracle.net.wallet_location=${ojp.server.oracle.wallet.location}&\
oracle.net.ssl_server_dn_match=trueSQL Server:
ojp.datasource.url=jdbc:ojp[localhost:1059]_sqlserver://host:1433;\
databaseName=mydb;encrypt=true;\
trustStore=${ojp.server.sqlserver.truststore};\
trustStorePassword=${ojp.server.sqlserver.truststorePassword}DB2:
ojp.datasource.url=jdbc:ojp[localhost:1059]_db2://host:50001/mydb:\
sslConnection=true;\
sslTrustStoreLocation=${ojp.server.db2.truststore};\
sslTrustStorePassword=${ojp.server.db2.truststorePassword};For comprehensive SSL/TLS configuration examples and best practices, see the SSL/TLS Certificate Configuration Guide.
The dataSource specification in parentheses within the OJP connection section specifies which configuration to use:
- No parameter: Uses "default" datasource configuration
(myApp): Uses configuration prefixed with "myApp."(analytics): Uses configuration prefixed with "analytics."
// Examples of different datasource usage
Connection mainConn = DriverManager.getConnection(
"jdbc:ojp[localhost:1059(mainApp)]_postgres:mydb", "user", "pass");
Connection analyticsConn = DriverManager.getConnection(
"jdbc:ojp[localhost:1059(analytics)]_postgres:mydb", "user", "pass");
Connection defaultConn = DriverManager.getConnection(
"jdbc:ojp[localhost:1059]_postgres:mydb", "user", "pass"); // Uses default configWhen using OJP with regular (non-XA) connections, disable any existing connection pooling in your application (such as HikariCP, C3P0, or DBCP2) since OJP handles connection pooling at the proxy level. This prevents double-pooling and ensures optimal performance.
Important: OJP will not work properly if another connection pool is enabled on the application side for regular connections. Make sure to disable all application-level connection pooling before using OJP.
XA Connections: When using OjpXADataSource for distributed transactions (XA mode), by default OJP uses server-side backend session pooling with Apache Commons Pool 2 if no other OJP XA SPI implementation is provided. The server manages PostgreSQL XAConnection pooling to ensure:
- Physical XAConnection reuse across multiple transactions
- Dual-condition session lifecycle (returned only when transaction complete AND client XAConnection closed)
- Dynamic pool rebalancing during server failures/recoveries
- Proper XA spec compliance (connection properties persist across transactions)
See XA Management Guide for comprehensive XA pooling documentation.
Each datasource name creates a separate connection pool on the server side, even when connecting to the same database. This provides:
- Configuration isolation between different application components
- Independent monitoring and metrics per datasource
- Fine-grained resource control
- Better troubleshooting capabilities
The multi-datasource feature is fully backward compatible:
- Existing applications without
dataSourceparameter continue to work unchanged - Existing
ojp.propertiesfiles without datasource prefixes continue to work as "default" datasource - No changes required for existing deployments unless you want to use multi-datasource features
- SSL/TLS Certificate Configuration Guide - Complete guide for configuring SSL/TLS certificates with property placeholders
- OJP Server Configuration - Server startup options and runtime configuration
- Example Configuration Properties - Complete example configuration file with all settings