-
Notifications
You must be signed in to change notification settings - Fork 120
Java EE Configuration
<dependency>
<groupId>com.vladmihalcea.flexy-pool</groupId>
<artifactId>flexy-java-ee</artifactId>
<version>${flexy-pool.version}</version>
</dependency>
In a Java EE environment, the DataSource is managed/provided by the Application Server through a JNDI lookup. Each Application server has a specific way of setting up a DataSource and the actual implementation doesn’t allow adjusting the pool size dynamically. In most Java EE applications, FlexyPool can only monitor the connection pool usage, without providing a dynamic pool sizing strategy.
Because we operate in a managed environment, we can no longer configure the DataSource programatically, so we need to use the declarative configuration support.
By default, FlexyPool looks for the flexy-pool.properties file in the current Class-path. The location can be customized using the flexy.pool.properties.path System property , which can be an:
-
URL (e.g. file:/D:/wrk/vladmihalcea/flexy-pool/flexy-pool-core/target/test-classes/flexy-pool.properties)
-
File system path (e.g. D:\wrk\vladmihalcea\flexy-pool\flexy-pool-core\target\test-classes\flexy-pool.properties)
-
Class-path nested path (e.g. nested/fp.properties)
The properties file may contain the following configuration options:
Parameter name | Optional | Default value | Description |
---|---|---|---|
flexy.pool.data.source.unique.name |
false |
N/A |
Each FlexyPool instance requires a unique name so that JMX domains won’t clash |
flexy.pool.data.source.jndi.name |
true |
N/A |
The JNDI DataSource location |
flexy.pool.data.source.jndi.lazy.lookup |
true |
false |
Whether to lookup the DataSource lazily (useful when the target DataSource is not available when the FlexyPoolDataSource is instantiated) |
flexy.pool.data.source.class.name |
true |
N/A |
The DataSource can be instantiated at Runtime using this Class name |
flexy.pool.data.source.property.* |
true |
N/A |
If the DataSource is instantiated at Runtime, each flexy.pool.data.source.property.${java-bean-property} will set the java-bean-property of the newly instantiated DataSource (e.g. flexy.pool.data.source.property.user=sa) |
flexy.pool.adapter.factory |
true |
DataSourcePoolAdapter.FACTORY |
Specifies the PoolAdaptorFactory, in case the DataSource supports dynamic sizing. By default it uses the generic DataSourcePoolAdapter which doesn’t support auto-scaling |
flexy.pool.metrics.factory |
true |
DropwizardMetrics.FACTORY |
Specifies the MetricsFactory used for creating Metrics |
flexy.pool.metrics.reporter.log.millis |
true |
TimeUnit.MINUTES.toMillis(5) |
Specifies the metrics log reported interval |
flexy.pool.metrics.reporter.jmx.enable |
true |
true |
Specifies if the jmx reporting should be enabled |
flexy.pool.metrics.reporter.jmx.auto.start |
true |
false |
Specifies if the jmx service should be auto-started (set this to true in Java EE environments) |
flexy.pool.strategies.factory.resolver |
true |
N/A |
Specifies a ConnectionAcquiringStrategyFactoryResolver class to be used for obtaining a list of ConnectionAcquiringStrategyFactory objects. This should be set only if the PoolAdaptor supports accessing the DataSource pool size. |
If you are using Hibernate, you can substitute the JPA configured DataSource (e.g. defined in persistence.xml) with FlexyPoolDataSource by adding the following hibernate.connection.provider_class property to your existing JPA configuration:
<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="persistenceUnit" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>java:/comp/env/jdbc/hsqldb</jta-data-source>
<properties>
<property name="hibernate.archive.autodetection"
value="class, hbm"/>
<property name="hibernate.dialect"
value="org.hibernate.dialect.HSQLDialect"/>
<property name="hibernate.transaction.jta.platform"
value="org.hibernate.service.jta.platform.internal.BitronixJtaPlatform"/>
<property name="hibernate.hbm2ddl.auto"
value="update"/>
<property name="hibernate.connection.provider_class"
value="com.vladmihalcea.flexypool.adaptor.FlexyPoolHibernateConnectionProvider"/>
</properties>
</persistence-unit>
</persistence>
When Hibernate bootstraps, the FlexyPoolHibernateConnectionProvider will take the existing DataSource and decorate it with the FlexyPoolDataSource proxy.
You can now even pass FlexyPool configuration properies via JPA or Hibernate, as in the following example:
<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="persistenceUnit" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>java:/comp/env/jdbc/hsqldb</jta-data-source>
<properties>
<property name="hibernate.archive.autodetection"
value="class, hbm"/>
<property name="hibernate.dialect"
value="org.hibernate.dialect.HSQLDialect"/>
<property name="hibernate.transaction.jta.platform"
value="org.hibernate.service.jta.platform.internal.BitronixJtaPlatform"/>
<property name="hibernate.hbm2ddl.auto"
value="update"/>
<property name="hibernate.connection.provider_class"
value="com.vladmihalcea.flexypool.adaptor.FlexyPoolHibernateConnectionProvider"/>
<property name="flexy.pool.data.source.unique.name"
value="ds-jdbc-hsqldb"/>
</properties>
</persistence-unit>
</persistence>
In the example above, the flexy.pool.data.source.unique.name
configuration property from the persistence.xml
configuration file will override the one found in the flexy-pool.properties
file.
We can instantiate the actual DataSource when FlexyPool is initialized. For example, if we use the following properties:
flexy.pool.data.source.unique.name=unique-name
flexy.pool.data.source.class.name=org.hsqldb.jdbc.JDBCDataSource
flexy.pool.data.source.property.user=sa
flexy.pool.data.source.property.password=
flexy.pool.data.source.property.url=jdbc:hsqldb:mem:test
flexy.pool.metrics.reporter.jmx.auto.start=true
and let’s say we are using the following DataSourceDefinition:
@DataSourceDefinition(
name = "java:global/jdbc/flexypool",
className = "com.vladmihalcea.flexypool.FlexyPoolDataSource")
@Stateless
public class FlexyPoolDataSourceConfiguration {
}
The persistence.xml uses the FlexyPoolDataSource JNDI location:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="persistenceUnit" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>java:global/jdbc/flexypool</jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
<property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform"/>
</properties>
</persistence-unit>
</persistence>
The FlexyPoolDataSource is instantiated using the currently available configuration file and it’s made available through JNDI.
The actual DataSource might be already available in JNDI (e.g. java:global/jdbc/default).
The persistence.xml is configured like this:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="persistenceUnit" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>java:global/jdbc/flexypool</jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
<property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform"/>
</properties>
</persistence-unit>
</persistence>
We now need to register the FlexyPoolDataSource under the java:global/jdbc/flexypool JNDI name:
@DataSourceDefinition(
name = "java:global/jdbc/default",
className = "org.hsqldb.jdbc.JDBCDataSource",
url = "jdbc:hsqldb:mem:test",
initialPoolSize = 3,
maxPoolSize = 5
)
@Stateless
public class DefaultDataSourceConfiguration {
}
@DataSourceDefinition(
name = "java:global/jdbc/flexypool",
className = "com.vladmihalcea.flexypool.FlexyPoolDataSource")
@Stateless
public class FlexyPoolDataSourceConfiguration {
}
And we need to instruct FlexyPool to locate the actual DataSource from JNDI:
flexy.pool.data.source.unique.name=unique-name
flexy.pool.data.source.jndi.name=java:global/jdbc/default
flexy.pool.metrics.reporter.jmx.auto.start=true