Fixed issue 29564: Merge Apache JDBC Connection Pool
authorInigo Sanchez <inigo.sanchez@openbravo.com>
Thu, 06 Aug 2015 09:46:54 +0200
changeset 27278 30caa81f847b
parent 27209 0c08e36aad01 (current diff)
parent 27277 ca0d0e8fbd3d (diff)
child 27279 3e0722a915a6
Fixed issue 29564: Merge Apache JDBC Connection Pool
lib/runtime/postgresql-9.0-801.jdbc4.jar
--- a/.classpath.template	Wed Aug 05 12:33:11 2015 +0200
+++ b/.classpath.template	Thu Aug 06 09:46:54 2015 +0200
@@ -5,6 +5,7 @@
 	<classpathentry combineaccessrules="false" exported="true" kind="src" path="/OpenbravoTrl"/>
 	<classpathentry combineaccessrules="false" exported="true" kind="src" path="/OpenbravoWAD"/>
 	<classpathentry including="**/*.ext|**/*.ftl|**/*.java|**/*.oaw|**/*.properties|**/*.xml|**/*.xpt|**/*.xslt" kind="src" path="src"/>
+	<classpathentry kind="src" path="modules/org.openbravo.apachejdbcconnectionpool/src"/>
 	<classpathentry kind="src" path="modules/org.openbravo.client.widgets/src"/>
 	<classpathentry kind="src" path="modules/org.openbravo.client.htmlwidget/src"/>
 	<classpathentry kind="src" path="modules/org.openbravo.base.weld/src"/>
--- a/build.xml	Wed Aug 05 12:33:11 2015 +0200
+++ b/build.xml	Thu Aug 06 09:46:54 2015 +0200
@@ -1088,7 +1088,7 @@
         <pathelement path="${base.lib}/runtime/log4j-1.2.16.jar" />
         <pathelement path="${base.lib}/runtime/commons-pool-1.5.6.jar" />
         <pathelement path="${base.lib}/runtime/commons-dbcp-1.4.jar" />
-        <pathelement path="${base.lib}/runtime/postgresql-9.0-801.jdbc4.jar" />
+        <pathelement path="${base.lib}/runtime/postgresql-9.4-1201.jdbc4.jar" />
         <pathelement path="${base.lib}/runtime/ojdbc6.jar" />
         <pathelement path="${base.lib}/runtime/commons-collectionsi-3.2.1.jar" />
         <pathelement path="${base.lib}/runtime/ant-1.9.2.jar" />
--- a/config/Openbravo.properties.template	Wed Aug 05 12:33:11 2015 +0200
+++ b/config/Openbravo.properties.template	Thu Aug 06 09:46:54 2015 +0200
@@ -10,7 +10,7 @@
 # * under the License. 
 # * The Original Code is Openbravo ERP. 
 # * The Initial Developer of the Original Code is Openbravo SLU 
-# * All portions are Copyright (C) 2007-2012 Openbravo SLU 
+# * All portions are Copyright (C) 2007-2015 Openbravo SLU 
 # * All Rights Reserved. 
 # * Contributor(s):  ______________________________________.
 # ************************************************************************
@@ -81,6 +81,25 @@
 bbdd.password=tad
 bbdd.sessionConfig=select update_dateFormat('DD-MM-YYYY')
 
+######################
+# DB connection pool #
+######################
+
+db.externalPoolClassName=org.openbravo.apachejdbcconnectionpool.JdbcExternalConnectionPool
+
+# Documentation at http://wiki.openbravo.com/wiki/Modules:Apache_JDBC_Connection_Pool#Pool_Configuration
+db.pool.initialSize=1
+db.pool.minIdle=5
+db.pool.maxActive=10000
+db.pool.timeBetweenEvictionRunsMillis=60000
+db.pool.minEvictableIdleTimeMillis=120000
+db.pool.removeAbandoned=false
+db.pool.testOnBorrow=true
+db.pool.testWhileIdle=false
+db.pool.testOnReturn=false
+db.pool.validationQuery=SELECT 1 FROM DUAL
+db.pool.validationInterval=30000
+
 ##################
 # Tomcat manager #
 ##################
--- a/legal/Licensing.txt	Wed Aug 05 12:33:11 2015 +0200
+++ b/legal/Licensing.txt	Thu Aug 06 09:46:54 2015 +0200
@@ -123,7 +123,7 @@
 All files under Apache Software License 2.0, available at
 http://www.apache.org/licenses/LICENSE-2.0
 
-# postgresql-9.0-801.jdbc4.jar
+# postgresql-9.4-1201.jdbc4.jar
 Under the BSD license, also available at http://jdbc.postgresql.org/license.html  
 
 # xstream-1.3.1.jar
@@ -256,6 +256,8 @@
 # httpclient-4.0.jar
 # httpmime-4.1.jar
 # guice-2.0.jar
+# tomcat-juli.jar
+# tomcat-jdbc.jar
 Under the Apache 2.0 license (included as Apache_license-2.0.txt in this folder)
 
 # jslint4java-1.4.7.jar
Binary file lib/runtime/postgresql-9.0-801.jdbc4.jar has changed
Binary file lib/runtime/postgresql-9.4-1201.jdbc4.jar has changed
Binary file modules/org.openbravo.apachejdbcconnectionpool/lib/runtime/tomcat-jdbc.jar has changed
Binary file modules/org.openbravo.apachejdbcconnectionpool/lib/runtime/tomcat-juli.jar has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/org.openbravo.apachejdbcconnectionpool/src-db/database/sourcedata/AD_MODULE.xml	Thu Aug 06 09:46:54 2015 +0200
@@ -0,0 +1,27 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<data>
+<!--8A098711BB324335A19833286BDB093D--><AD_MODULE>
+<!--8A098711BB324335A19833286BDB093D-->  <AD_MODULE_ID><![CDATA[8A098711BB324335A19833286BDB093D]]></AD_MODULE_ID>
+<!--8A098711BB324335A19833286BDB093D-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--8A098711BB324335A19833286BDB093D-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--8A098711BB324335A19833286BDB093D-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--8A098711BB324335A19833286BDB093D-->  <NAME><![CDATA[Apache External Connection Pool]]></NAME>
+<!--8A098711BB324335A19833286BDB093D-->  <VERSION><![CDATA[1.0.1]]></VERSION>
+<!--8A098711BB324335A19833286BDB093D-->  <DESCRIPTION><![CDATA[Apache External Connection Pool]]></DESCRIPTION>
+<!--8A098711BB324335A19833286BDB093D-->  <HELP><![CDATA[This module implements the Apache JDBC Connection Pool (http://wiki.openbravo.com/wiki/Modules:Apache_JDBC_Connection_Pool).]]></HELP>
+<!--8A098711BB324335A19833286BDB093D-->  <TYPE><![CDATA[M]]></TYPE>
+<!--8A098711BB324335A19833286BDB093D-->  <LICENSE><![CDATA[Licensed under the Openbravo Public License version 1.1.
+You may obtain a copy of the License at http://www.openbravo.com/legal/license.html or in the legal folder of the Openbravo ERP core distribution.]]></LICENSE>
+<!--8A098711BB324335A19833286BDB093D-->  <JAVAPACKAGE><![CDATA[org.openbravo.apachejdbcconnectionpool]]></JAVAPACKAGE>
+<!--8A098711BB324335A19833286BDB093D-->  <LICENSETYPE><![CDATA[OBPL]]></LICENSETYPE>
+<!--8A098711BB324335A19833286BDB093D-->  <AUTHOR><![CDATA[Openbravo S.L.U.]]></AUTHOR>
+<!--8A098711BB324335A19833286BDB093D-->  <ISTRANSLATIONREQUIRED><![CDATA[N]]></ISTRANSLATIONREQUIRED>
+<!--8A098711BB324335A19833286BDB093D-->  <HASCHARTOFACCOUNTS><![CDATA[N]]></HASCHARTOFACCOUNTS>
+<!--8A098711BB324335A19833286BDB093D-->  <ISTRANSLATIONMODULE><![CDATA[N]]></ISTRANSLATIONMODULE>
+<!--8A098711BB324335A19833286BDB093D-->  <HASREFERENCEDATA><![CDATA[N]]></HASREFERENCEDATA>
+<!--8A098711BB324335A19833286BDB093D-->  <UPDATEINFO><![CDATA[fixed issue #26663: configuration is read from servlet context]]></UPDATEINFO>
+<!--8A098711BB324335A19833286BDB093D-->  <ISCOMMERCIAL><![CDATA[N]]></ISCOMMERCIAL>
+<!--8A098711BB324335A19833286BDB093D-->  <ISTRIALALLOWED><![CDATA[N]]></ISTRIALALLOWED>
+<!--8A098711BB324335A19833286BDB093D--></AD_MODULE>
+
+</data>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/org.openbravo.apachejdbcconnectionpool/src-db/database/sourcedata/AD_MODULE_DBPREFIX.xml	Thu Aug 06 09:46:54 2015 +0200
@@ -0,0 +1,12 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<data>
+<!--5717805411944D0298C5670BC6B6F2B6--><AD_MODULE_DBPREFIX>
+<!--5717805411944D0298C5670BC6B6F2B6-->  <AD_MODULE_DBPREFIX_ID><![CDATA[5717805411944D0298C5670BC6B6F2B6]]></AD_MODULE_DBPREFIX_ID>
+<!--5717805411944D0298C5670BC6B6F2B6-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--5717805411944D0298C5670BC6B6F2B6-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--5717805411944D0298C5670BC6B6F2B6-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--5717805411944D0298C5670BC6B6F2B6-->  <AD_MODULE_ID><![CDATA[8A098711BB324335A19833286BDB093D]]></AD_MODULE_ID>
+<!--5717805411944D0298C5670BC6B6F2B6-->  <NAME><![CDATA[JDBCCP]]></NAME>
+<!--5717805411944D0298C5670BC6B6F2B6--></AD_MODULE_DBPREFIX>
+
+</data>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/org.openbravo.apachejdbcconnectionpool/src-db/database/sourcedata/AD_MODULE_DEPENDENCY.xml	Thu Aug 06 09:46:54 2015 +0200
@@ -0,0 +1,17 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<data>
+<!--1467C397BC5F4999A5606F39CD6FF8A4--><AD_MODULE_DEPENDENCY>
+<!--1467C397BC5F4999A5606F39CD6FF8A4-->  <AD_MODULE_DEPENDENCY_ID><![CDATA[1467C397BC5F4999A5606F39CD6FF8A4]]></AD_MODULE_DEPENDENCY_ID>
+<!--1467C397BC5F4999A5606F39CD6FF8A4-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--1467C397BC5F4999A5606F39CD6FF8A4-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--1467C397BC5F4999A5606F39CD6FF8A4-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--1467C397BC5F4999A5606F39CD6FF8A4-->  <AD_MODULE_ID><![CDATA[8A098711BB324335A19833286BDB093D]]></AD_MODULE_ID>
+<!--1467C397BC5F4999A5606F39CD6FF8A4-->  <AD_DEPENDENT_MODULE_ID><![CDATA[7E48CDD73B7E493A8BED4F7253E7C989]]></AD_DEPENDENT_MODULE_ID>
+<!--1467C397BC5F4999A5606F39CD6FF8A4-->  <STARTVERSION><![CDATA[2.1.21974]]></STARTVERSION>
+<!--1467C397BC5F4999A5606F39CD6FF8A4-->  <ISINCLUDED><![CDATA[N]]></ISINCLUDED>
+<!--1467C397BC5F4999A5606F39CD6FF8A4-->  <DEPENDANT_MODULE_NAME><![CDATA[Openbravo 3.0 Framework]]></DEPENDANT_MODULE_NAME>
+<!--1467C397BC5F4999A5606F39CD6FF8A4-->  <DEPENDENCY_ENFORCEMENT><![CDATA[MAJOR]]></DEPENDENCY_ENFORCEMENT>
+<!--1467C397BC5F4999A5606F39CD6FF8A4-->  <USER_EDITABLE_ENFORCEMENT><![CDATA[N]]></USER_EDITABLE_ENFORCEMENT>
+<!--1467C397BC5F4999A5606F39CD6FF8A4--></AD_MODULE_DEPENDENCY>
+
+</data>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/org.openbravo.apachejdbcconnectionpool/src/org/openbravo/apachejdbcconnectionpool/ConnectionInitializerInterceptor.java	Thu Aug 06 09:46:54 2015 +0200
@@ -0,0 +1,82 @@
+/*
+ *************************************************************************
+ * The contents of this file are subject to the Openbravo  Public  License
+ * Version  1.1  (the  "License"),  being   the  Mozilla   Public  License
+ * Version 1.1  with a permitted attribution clause; you may not  use this
+ * file except in compliance with the License. You  may  obtain  a copy of
+ * the License at http://www.openbravo.com/legal/license.html
+ * Software distributed under the License  is  distributed  on  an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific  language  governing  rights  and  limitations
+ * under the License.
+ * The Original Code is Openbravo ERP.
+ * The Initial Developer of the Original Code is Openbravo SLU
+ * All portions are Copyright (C) 2014-2015 Openbravo SLU
+ * All Rights Reserved.
+ * Contributor(s):  ______________________________________.
+ ************************************************************************
+ */
+package org.openbravo.apachejdbcconnectionpool;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Properties;
+
+import org.apache.tomcat.jdbc.pool.ConnectionPool;
+import org.apache.tomcat.jdbc.pool.JdbcInterceptor;
+import org.apache.tomcat.jdbc.pool.PooledConnection;
+import org.openbravo.base.exception.OBException;
+import org.openbravo.base.session.OBPropertiesProvider;
+import org.openbravo.database.PoolInterceptorProvider;
+import org.openbravo.database.SessionInfo;
+
+/**
+ * This interceptor allows to act whenever a connection is requested from the pool and whenever any
+ * operation is invoked on a connection provided by Apache JDBC Connection Pool.
+ */
+public class ConnectionInitializerInterceptor extends JdbcInterceptor implements
+    PoolInterceptorProvider {
+
+  String rbdms = (String) OBPropertiesProvider.getInstance().getOpenbravoProperties()
+      .get("bbdd.rdbms");
+
+  /**
+   * This method is called each time the connection is borrowed from the pool and it is used to
+   * initialize prepareStatement.
+   */
+  @Override
+  public void reset(ConnectionPool parent, PooledConnection con) {
+    if (con != null) {
+      HashMap<Object, Object> attributes = con.getAttributes();
+      Boolean connectionInitialized = (Boolean) attributes.get("OB_INITIALIZED");
+      if (connectionInitialized == null || connectionInitialized == false) {
+        SessionInfo.setDBSessionInfo(con.getConnection(), rbdms);
+        PreparedStatement pstmt = null;
+        try {
+          final Properties props = OBPropertiesProvider.getInstance().getOpenbravoProperties();
+          final String dbSessionConfig = props.getProperty("bbdd.sessionConfig");
+          pstmt = con.getConnection().prepareStatement(dbSessionConfig);
+          pstmt.executeQuery();
+        } catch (Exception e) {
+          throw new IllegalStateException(e);
+        } finally {
+          try {
+            if (pstmt != null && !pstmt.isClosed()) {
+              pstmt.close();
+            }
+          } catch (SQLException e) {
+            throw new OBException(e);
+          }
+        }
+        attributes.put("OB_INITIALIZED", true);
+      }
+    }
+  }
+
+  @Override
+  public String getPoolInterceptorsClassNames() {
+    String fullClassName = this.getClass().getName();
+    return fullClassName + ";";
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/org.openbravo.apachejdbcconnectionpool/src/org/openbravo/apachejdbcconnectionpool/JdbcExternalConnectionPool.java	Thu Aug 06 09:46:54 2015 +0200
@@ -0,0 +1,239 @@
+/*
+ *************************************************************************
+ * The contents of this file are subject to the Openbravo  Public  License
+ * Version  1.1  (the  "License"),  being   the  Mozilla   Public  License
+ * Version 1.1  with a permitted attribution clause; you may not  use this
+ * file except in compliance with the License. You  may  obtain  a copy of
+ * the License at http://www.openbravo.com/legal/license.html
+ * Software distributed under the License  is  distributed  on  an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific  language  governing  rights  and  limitations
+ * under the License.
+ * The Original Code is Openbravo ERP.
+ * The Initial Developer of the Original Code is Openbravo SLU
+ * All portions are Copyright (C) 2014-2015 Openbravo SLU
+ * All Rights Reserved.
+ * Contributor(s):  ______________________________________.
+ ************************************************************************
+ */
+package org.openbravo.apachejdbcconnectionpool;
+
+import java.sql.Connection;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.tomcat.jdbc.pool.DataSource;
+import org.apache.tomcat.jdbc.pool.PoolProperties;
+import org.openbravo.base.exception.OBException;
+import org.openbravo.base.session.OBPropertiesProvider;
+import org.openbravo.database.ExternalConnectionPool;
+import org.openbravo.database.PoolInterceptorProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * JdbcExternalConnectionPool manages all the functionality of the Apache JDBC Connection Pool. This
+ * class provides convenience methods to get a connection, close the pool and other actions.
+ */
+public class JdbcExternalConnectionPool extends ExternalConnectionPool {
+
+  final static private Logger log = LoggerFactory.getLogger(JdbcExternalConnectionPool.class);
+
+  private DataSource dataSource = null;
+
+  /**
+   * This method loads all the interceptors of apache jdbc connection pool injected with weld.
+   */
+  @Override
+  public void loadInterceptors(List<PoolInterceptorProvider> interceptors) {
+    String currentInterceptors = this.getDataSource().getJdbcInterceptors();
+    for (PoolInterceptorProvider interceptor : interceptors) {
+      currentInterceptors += interceptor.getPoolInterceptorsClassNames();
+    }
+    this.getDataSource().setJdbcInterceptors(currentInterceptors);
+  }
+
+  /**
+   * Gets the data source of apache jdbc connection pool.
+   */
+  public DataSource getDataSource() {
+    return dataSource;
+  }
+
+  /**
+   * This method provided a connection of apache jdbc connection pool. Apache jdbc connection pool
+   * is initialized in the first call to this method.
+   */
+  @Override
+  public Connection getConnection() {
+    if (dataSource == null) {
+      initPool();
+    }
+    Connection connection = null;
+    try {
+      connection = dataSource.getConnection();
+      // All connections are setting autoCommit to true. DAL is taking into account his logical and
+      // DAL is setting autoCommint to false to maintain transactional way of working.
+      connection.setAutoCommit(true);
+    } catch (Exception e) {
+      log.error("Error while retrieving connection: ", e);
+      throw new OBException(e);
+    }
+    return connection;
+  }
+
+  private void initPool() {
+    dataSource = new DataSource();
+    dataSource.setPoolProperties(getPoolProperties());
+  }
+
+  private PoolProperties getPoolProperties() {
+    String obUrl = (String) OBPropertiesProvider.getInstance().getOpenbravoProperties()
+        .get("bbdd.url");
+    String sid = (String) OBPropertiesProvider.getInstance().getOpenbravoProperties()
+        .get("bbdd.sid");
+    String driver = (String) OBPropertiesProvider.getInstance().getOpenbravoProperties()
+        .get("bbdd.driver");
+    String username = (String) OBPropertiesProvider.getInstance().getOpenbravoProperties()
+        .get("bbdd.user");
+    String password = (String) OBPropertiesProvider.getInstance().getOpenbravoProperties()
+        .get("bbdd.password");
+    String rbdms = (String) OBPropertiesProvider.getInstance().getOpenbravoProperties()
+        .get("bbdd.rdbms");
+
+    PoolProperties poolProperties = new PoolProperties();
+    if ("POSTGRE".equals(rbdms)) {
+      poolProperties.setUrl(obUrl + "/" + sid);
+    } else {
+      poolProperties.setUrl(obUrl);
+    }
+    poolProperties.setDriverClassName(driver);
+    poolProperties.setUsername(username);
+    poolProperties.setPassword(password);
+
+    Properties poolPropertiesConfig = new Properties();
+    poolPropertiesConfig = OBPropertiesProvider.getInstance().getOpenbravoProperties();
+    if (poolPropertiesConfig.getProperty("db.pool.initialSize") != null) {
+      poolProperties.setInitialSize(getIntProperty(poolPropertiesConfig, "db.pool.initialSize"));
+    }
+    if (poolPropertiesConfig.getProperty("db.pool.maxActive") != null) {
+      poolProperties.setMaxActive(getIntProperty(poolPropertiesConfig, "db.pool.maxActive"));
+    }
+    if (poolPropertiesConfig.getProperty("db.pool.minIdle") != null) {
+      poolProperties.setMinIdle(getIntProperty(poolPropertiesConfig, "db.pool.minIdle"));
+    }
+    if (poolPropertiesConfig.getProperty("db.pool.timeBetweenEvictionRunsMillis") != null) {
+      poolProperties.setTimeBetweenEvictionRunsMillis(getIntProperty(poolPropertiesConfig,
+          "db.pool.timeBetweenEvictionRunsMillis"));
+    }
+    if (poolPropertiesConfig.getProperty("db.pool.minEvictableIdleTimeMillis") != null) {
+      poolProperties.setMinEvictableIdleTimeMillis(getIntProperty(poolPropertiesConfig,
+          "db.pool.minEvictableIdleTimeMillis"));
+    }
+    if (poolPropertiesConfig.getProperty("db.pool.removeAbandoned") != null) {
+      poolProperties.setRemoveAbandoned(getBooleanProperty(poolPropertiesConfig,
+          "db.pool.removeAbandoned"));
+    }
+    if (poolPropertiesConfig.getProperty("db.pool.testWhileIdle") != null) {
+      poolProperties.setTestWhileIdle(getBooleanProperty(poolPropertiesConfig,
+          "db.pool.testWhileIdle"));
+    }
+    if (poolPropertiesConfig.getProperty("db.pool.testOnBorrow") != null) {
+      poolProperties.setTestOnBorrow(getBooleanProperty(poolPropertiesConfig,
+          "db.pool.testOnBorrow"));
+    }
+    if (poolPropertiesConfig.getProperty("db.pool.testOnReturn") != null) {
+      poolProperties.setTestOnReturn(getBooleanProperty(poolPropertiesConfig,
+          "db.pool.testOnReturn"));
+    }
+    if (poolPropertiesConfig.getProperty("db.pool.validationInterval") != null) {
+      poolProperties.setValidationInterval(getIntProperty(poolPropertiesConfig,
+          "db.pool.validationInterval"));
+    }
+    if (poolPropertiesConfig.getProperty("db.pool.validationQuery") != null) {
+      poolProperties
+          .setValidationQuery(poolPropertiesConfig.getProperty("db.pool.validationQuery"));
+    }
+    if (poolPropertiesConfig.getProperty("db.pool.defaultTransactionIsolation") != null) {
+      poolProperties.setDefaultTransactionIsolation(getIntProperty(poolPropertiesConfig,
+          "db.pool.defaultTransactionIsolation"));
+    }
+    if (poolPropertiesConfig.getProperty("db.pool.maxIdle") != null) {
+      poolProperties.setMaxIdle(getIntProperty(poolPropertiesConfig, "db.pool.maxIdle"));
+    }
+    if (poolPropertiesConfig.getProperty("db.pool.maxWait") != null) {
+      poolProperties.setMaxWait(getIntProperty(poolPropertiesConfig, "db.pool.maxWait"));
+    }
+    if (poolPropertiesConfig.getProperty("db.pool.numTestsPerEvictionRun") != null) {
+      poolProperties.setNumTestsPerEvictionRun(getIntProperty(poolPropertiesConfig,
+          "db.pool.numTestsPerEvictionRun"));
+    }
+    if (poolPropertiesConfig.getProperty("db.pool.removeAbandonedTimeout") != null) {
+      poolProperties.setRemoveAbandonedTimeout(getIntProperty(poolPropertiesConfig,
+          "db.pool.removeAbandonedTimeout"));
+    }
+    if (poolPropertiesConfig.getProperty("db.pool.accessToUnderlyingConnectionAllowed") != null) {
+      poolProperties.setAccessToUnderlyingConnectionAllowed(getBooleanProperty(
+          poolPropertiesConfig, "db.pool.accessToUnderlyingConnectionAllowed"));
+    }
+    if (poolPropertiesConfig.getProperty("db.pool.defaultAutoCommit") != null) {
+      poolProperties.setDefaultAutoCommit(getBooleanProperty(poolPropertiesConfig,
+          "db.pool.defaultAutoCommit"));
+    }
+    if (poolPropertiesConfig.getProperty("db.pool.defaultReadOnly") != null) {
+      poolProperties.setDefaultReadOnly(getBooleanProperty(poolPropertiesConfig,
+          "db.pool.defaultReadOnly"));
+    }
+    if (poolPropertiesConfig.getProperty("db.pool.logAbandoned") != null) {
+      poolProperties.setLogAbandoned(getBooleanProperty(poolPropertiesConfig,
+          "db.pool.logAbandoned"));
+    }
+    if (poolPropertiesConfig.getProperty("db.pool.testOnConnect") != null) {
+      poolProperties.setTestOnConnect(getBooleanProperty(poolPropertiesConfig,
+          "db.pool.testOnConnect"));
+    }
+    if (poolPropertiesConfig.getProperty("db.pool.connectionProperties") != null) {
+      poolProperties.setConnectionProperties(poolPropertiesConfig
+          .getProperty("db.pool.connectionProperties"));
+    }
+    if (poolPropertiesConfig.getProperty("db.pool.defaultCatalog") != null) {
+      poolProperties.setDefaultCatalog(poolPropertiesConfig.getProperty("db.pool.defaultCatalog"));
+    }
+    if (poolPropertiesConfig.getProperty("db.pool.validatorClassName") != null) {
+      poolProperties.setValidatorClassName(poolPropertiesConfig
+          .getProperty("db.pool.validatorClassName"));
+    }
+    if (poolPropertiesConfig.getProperty("db.pool.initSQL") != null) {
+      poolProperties.setInitSQL(poolPropertiesConfig.getProperty("db.pool.initSQL"));
+    }
+    if (poolPropertiesConfig.getProperty("db.pool.name") != null) {
+      poolProperties.setName(poolPropertiesConfig.getProperty("db.pool.name"));
+    }
+    poolProperties.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"
+        + "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer;"
+        + "org.openbravo.apachejdbcconnectionpool.ConnectionInitializerInterceptor;");
+    return poolProperties;
+  }
+
+  private boolean getBooleanProperty(Properties properties, String propertyName) {
+    return ("true".equals(properties.getProperty(propertyName)));
+  }
+
+  private int getIntProperty(Properties properties, String propertyName) {
+    return Integer.parseInt(properties.getProperty(propertyName).trim());
+  }
+
+  /**
+   * This method closes apache jdbc connection pool.
+   */
+  @Override
+  public void closePool() {
+    DataSource ds = getDataSource();
+    if (ds != null) {
+      // Closes the pool and all idle connections. true parameter is for close the active
+      // connections too.
+      ds.close(true);
+    }
+    super.closePool();
+  }
+}
--- a/modules/org.openbravo.client.kernel/src/org/openbravo/client/kernel/KernelInitializer.java	Wed Aug 05 12:33:11 2015 +0200
+++ b/modules/org.openbravo.client.kernel/src/org/openbravo/client/kernel/KernelInitializer.java	Thu Aug 06 09:46:54 2015 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2011-2014 Openbravo SLU 
+ * All portions are Copyright (C) 2011-2015 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -68,7 +68,7 @@
     // If an external connection pool is used, its injected interceptors are added to the pool
     String poolClassName = OBPropertiesProvider.getInstance().getOpenbravoProperties()
         .getProperty("db.externalPoolClassName");
-    if (poolClassName != null) {
+    if (poolClassName != null && !"".equals(poolClassName)) {
       try {
         ExternalConnectionPool pool = ExternalConnectionPool.getInstance(poolClassName);
         List<PoolInterceptorProvider> poolInterceptorList = new ArrayList<PoolInterceptorProvider>();
--- a/modules/org.openbravo.service.json/src/org/openbravo/service/json/JsonUtils.java	Wed Aug 05 12:33:11 2015 +0200
+++ b/modules/org.openbravo.service.json/src/org/openbravo/service/json/JsonUtils.java	Thu Aug 06 09:46:54 2015 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2009-2014 Openbravo SLU 
+ * All portions are Copyright (C) 2009-2015 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -44,6 +44,7 @@
 import org.openbravo.erpCommon.utility.OBError;
 import org.openbravo.erpCommon.utility.Utility;
 import org.openbravo.service.db.DalConnectionProvider;
+import org.postgresql.util.PSQLException;
 
 /**
  * Contains utility methods used in this module.
@@ -53,6 +54,9 @@
 public class JsonUtils {
   private static final Logger log = Logger.getLogger(JsonUtils.class);
 
+  /** PG returns this SQL state when query time out occurs */
+  private static final String PG_QUERY_CANCELED = "57014";
+
   /**
    * A utility method which retrieves the properties used for identifying an entity and its first
    * level references. Takes into accoun the different scenarios implemented in the
@@ -225,7 +229,9 @@
         error.put("type", "user");
         jsonResponse.put(JsonConstants.RESPONSE_ERROR, error);
       } else if (localThrowable instanceof SQLTimeoutException
-          || localThrowable instanceof QueryTimeoutException) {
+          || localThrowable instanceof QueryTimeoutException
+          || (localThrowable.getCause() instanceof PSQLException && PG_QUERY_CANCELED
+              .equals(((PSQLException) localThrowable.getCause()).getSQLState()))) {
         final JSONObject error = new JSONObject();
         error.put(
             "message",
--- a/modules/org.openbravo.v3/src-db/database/sourcedata/AD_MODULE_DEPENDENCY.xml	Wed Aug 05 12:33:11 2015 +0200
+++ b/modules/org.openbravo.v3/src-db/database/sourcedata/AD_MODULE_DEPENDENCY.xml	Thu Aug 06 09:46:54 2015 +0200
@@ -1,5 +1,19 @@
 <?xml version='1.0' encoding='UTF-8'?>
 <data>
+<!--48D556894CE54CF998DC97882E904CBD--><AD_MODULE_DEPENDENCY>
+<!--48D556894CE54CF998DC97882E904CBD-->  <AD_MODULE_DEPENDENCY_ID><![CDATA[48D556894CE54CF998DC97882E904CBD]]></AD_MODULE_DEPENDENCY_ID>
+<!--48D556894CE54CF998DC97882E904CBD-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--48D556894CE54CF998DC97882E904CBD-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--48D556894CE54CF998DC97882E904CBD-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--48D556894CE54CF998DC97882E904CBD-->  <AD_MODULE_ID><![CDATA[0138E7A89B5E4DC3932462252801FFBC]]></AD_MODULE_ID>
+<!--48D556894CE54CF998DC97882E904CBD-->  <AD_DEPENDENT_MODULE_ID><![CDATA[8A098711BB324335A19833286BDB093D]]></AD_DEPENDENT_MODULE_ID>
+<!--48D556894CE54CF998DC97882E904CBD-->  <STARTVERSION><![CDATA[1.0.1]]></STARTVERSION>
+<!--48D556894CE54CF998DC97882E904CBD-->  <ISINCLUDED><![CDATA[Y]]></ISINCLUDED>
+<!--48D556894CE54CF998DC97882E904CBD-->  <DEPENDANT_MODULE_NAME><![CDATA[Apache External Connection Pool]]></DEPENDANT_MODULE_NAME>
+<!--48D556894CE54CF998DC97882E904CBD-->  <DEPENDENCY_ENFORCEMENT><![CDATA[MAJOR]]></DEPENDENCY_ENFORCEMENT>
+<!--48D556894CE54CF998DC97882E904CBD-->  <USER_EDITABLE_ENFORCEMENT><![CDATA[N]]></USER_EDITABLE_ENFORCEMENT>
+<!--48D556894CE54CF998DC97882E904CBD--></AD_MODULE_DEPENDENCY>
+
 <!--4D11E3A70650475381139522373CD191--><AD_MODULE_DEPENDENCY>
 <!--4D11E3A70650475381139522373CD191-->  <AD_MODULE_DEPENDENCY_ID><![CDATA[4D11E3A70650475381139522373CD191]]></AD_MODULE_DEPENDENCY_ID>
 <!--4D11E3A70650475381139522373CD191-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
--- a/src-core/src/org/openbravo/base/ConnectionProviderContextListener.java	Wed Aug 05 12:33:11 2015 +0200
+++ b/src-core/src/org/openbravo/base/ConnectionProviderContextListener.java	Thu Aug 06 09:46:54 2015 +0200
@@ -1,6 +1,6 @@
 /*
  ************************************************************************************
- * Copyright (C) 2001-2010 Openbravo S.L.U.
+ * Copyright (C) 2001-2015 Openbravo S.L.U.
  * Licensed under the Apache Software License version 2.0
  * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
  * Unless required by applicable law or agreed to  in writing,  software  distributed
@@ -35,13 +35,14 @@
 public class ConnectionProviderContextListener implements ServletContextListener {
   public static final String POOL_ATTRIBUTE = "openbravoPool";
   private static Logger log4j = Logger.getLogger(ConnectionProviderContextListener.class);
+  private static ConnectionProvider pool;
 
   public void contextInitialized(ServletContextEvent event) {
     ServletContext context = event.getServletContext();
     ConfigParameters configParameters = ConfigParameters.retrieveFrom(context);
 
     try {
-      ConnectionProvider pool = createPool(configParameters);
+      pool = createPool(configParameters);
       context.setAttribute(POOL_ATTRIBUTE, pool);
     } catch (PoolNotFoundException e) {
       log4j.error("Unable to create a connection pool", e);
@@ -59,6 +60,10 @@
     return (ConnectionProvider) context.getAttribute(POOL_ATTRIBUTE);
   }
 
+  public static ConnectionProvider getPool() {
+    return pool;
+  }
+
   public static void reloadPool(ServletContext context) throws Exception {
     ConnectionProvider pool = getPool(context);
     if (pool instanceof ConnectionProviderImpl) {
--- a/src-core/src/org/openbravo/database/ConnectionProviderImpl.java	Wed Aug 05 12:33:11 2015 +0200
+++ b/src-core/src/org/openbravo/database/ConnectionProviderImpl.java	Thu Aug 06 09:46:54 2015 +0200
@@ -1,6 +1,6 @@
 /*
  ************************************************************************************
- * Copyright (C) 2001-2011 Openbravo S.L.U.
+ * Copyright (C) 2001-2015 Openbravo S.L.U.
  * Licensed under the Apache Software License version 2.0
  * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
  * Unless required by applicable law or agreed to  in writing,  software  distributed
@@ -39,6 +39,7 @@
   String bbdd = "";
   String rdbms = "";
   String contextName = "openbravo";
+  private String externalPoolClassName;
 
   private static ExternalConnectionPool externalConnectionPool;
 
@@ -78,7 +79,6 @@
       contextName = _context;
 
     String poolName = null;
-    String externalPoolClassName;
     String dbDriver = null;
     String dbServer = null;
     String dbLogin = null;
@@ -117,11 +117,12 @@
       log4j.debug("rdbms: " + rdbms);
     }
 
-    if (externalPoolClassName != null) {
+    if (externalPoolClassName != null && !"".equals(externalPoolClassName)) {
       try {
         externalConnectionPool = ExternalConnectionPool.getInstance(externalPoolClassName);
       } catch (Throwable e) {
         externalConnectionPool = null;
+        externalPoolClassName = null;
       }
     }
 
@@ -135,8 +136,13 @@
   }
 
   public void destroy(String name) throws Exception {
-    PoolingDriver driver = (PoolingDriver) DriverManager.getDriver("jdbc:apache:commons:dbcp:");
-    driver.closePool(name);
+    if (externalConnectionPool != null) {
+      externalConnectionPool.closePool();
+      externalConnectionPool = null;
+    } else {
+      PoolingDriver driver = (PoolingDriver) DriverManager.getDriver("jdbc:apache:commons:dbcp:");
+      driver.closePool(name);
+    }
   }
 
   public void reload(String file, boolean isRelative, String _context) throws Exception {
@@ -151,6 +157,17 @@
   public void addNewPool(String dbDriver, String dbServer, String dbLogin, String dbPassword,
       int minConns, int maxConns, double maxConnTime, String dbSessionConfig, String rdbms,
       String name) throws Exception {
+
+    if (this.defaultPoolName == null || this.defaultPoolName.equals("")) {
+      this.defaultPoolName = name;
+      this.bbdd = dbServer;
+      this.rdbms = rdbms;
+    }
+    if (externalConnectionPool != null) {
+      // No need to create and add a new pool
+      return;
+    }
+
     log4j.debug("Loading underlying JDBC driver.");
     try {
       Class.forName(dbDriver);
@@ -178,11 +195,6 @@
     PoolingDriver driver = (PoolingDriver) DriverManager.getDriver("jdbc:apache:commons:dbcp:");
     driver.registerPool(contextName + "_" + name, connectionPool);
 
-    if (this.defaultPoolName == null || this.defaultPoolName.equals("")) {
-      this.defaultPoolName = name;
-      this.bbdd = dbServer;
-      this.rdbms = rdbms;
-    }
   }
 
   public ObjectPool getPool(String poolName) throws PoolNotFoundException {
@@ -209,7 +221,7 @@
     return getConnection(defaultPoolName);
   }
 
-  /*
+  /**
    * Optimization, try to get the connection associated with the current thread, to always get the
    * same connection for all getConnection() calls inside a request.
    */
@@ -220,12 +232,7 @@
     // try to get the connection from the session to use a single connection for the whole request
     Connection conn = SessionInfo.getSessionConnection();
     if (conn == null) {
-      // No connection in the session, take a new one and attach it to the session
-      if (externalConnectionPool != null) {
-        conn = externalConnectionPool.getConnection();
-      } else {
-        conn = getNewConnection(poolName);
-      }
+      conn = getNewConnection(poolName);
       SessionInfo.setSessionConnection(conn);
     } else {
       // Update session info if needed
@@ -234,14 +241,37 @@
     return conn;
   }
 
-  private Connection getNewConnection() throws NoConnectionAvailableException {
-    return getNewConnection(defaultPoolName);
+  /**
+   * Gets a new connection without trying to obtain the sessions's one from available pool
+   */
+  private Connection getNewConnection(String poolName) throws NoConnectionAvailableException {
+    if (poolName == null || poolName.equals(""))
+      throw new NoConnectionAvailableException("Couldn´t get a connection for an unnamed pool");
+    Connection conn;
+    if (externalConnectionPool == null && externalPoolClassName != null
+        && !"".equals(externalPoolClassName)) {
+      try {
+        externalConnectionPool = ExternalConnectionPool.getInstance(externalPoolClassName);
+      } catch (Throwable e) {
+        externalConnectionPool = null;
+        externalPoolClassName = null;
+      }
+    }
+
+    if (externalConnectionPool != null) {
+      conn = externalConnectionPool.getConnection();
+    } else {
+      conn = getCommonsDbcpPoolConnection(poolName);
+    }
+
+    return conn;
   }
 
   /**
-   * Gets a new connection without trying to obtain the sessions's one
+   * Gets a new connection without trying to obtain the sessions's one from DBCP pool
    */
-  private Connection getNewConnection(String poolName) throws NoConnectionAvailableException {
+  private Connection getCommonsDbcpPoolConnection(String poolName)
+      throws NoConnectionAvailableException {
     if (poolName == null || poolName.equals(""))
       throw new NoConnectionAvailableException("Couldn´t get a connection for an unnamed pool");
     Connection conn = null;
@@ -303,7 +333,7 @@
   }
 
   public Connection getTransactionConnection() throws NoConnectionAvailableException, SQLException {
-    Connection conn = getNewConnection();
+    Connection conn = getNewConnection(defaultPoolName);
     if (conn == null)
       throw new NoConnectionAvailableException("Couldn´t get an available connection");
     conn.setAutoCommit(false);
--- a/src-core/src/org/openbravo/database/ExternalConnectionPool.java	Wed Aug 05 12:33:11 2015 +0200
+++ b/src-core/src/org/openbravo/database/ExternalConnectionPool.java	Thu Aug 06 09:46:54 2015 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2014 Openbravo SLU 
+ * All portions are Copyright (C) 2014-2015 Openbravo SLU 
  * All Rights Reserved. 
  ************************************************************************
  */
@@ -52,6 +52,13 @@
   }
 
   /**
+   * If the external connection pool should be closed this method should be overwritten
+   */
+  public void closePool() {
+    instance = null;
+  }
+
+  /**
    * If the external connection pool supports interceptors this method should be overwritten
    * 
    * @param interceptors
--- a/src-trl/.classpath	Wed Aug 05 12:33:11 2015 +0200
+++ b/src-trl/.classpath	Thu Aug 06 09:46:54 2015 +0200
@@ -6,8 +6,6 @@
 	<classpathentry combineaccessrules="false" kind="src" path="/OpenbravoCore"/>
 	<classpathentry kind="lib" path="/openbravo/lib/runtime/nekohtml.jar"/>
 	<classpathentry kind="lib" path="/openbravo/lib/runtime/xercesImpl.jar"/>
-	<classpathentry kind="lib" path="/openbravo/lib/runtime/ojdbc6.jar"/>
-	<classpathentry kind="lib" path="/openbravo/lib/runtime/postgresql-9.0-801.jdbc4.jar"/>
 	<classpathentry kind="lib" path="/openbravo/lib/runtime/log4j-1.2.16.jar"/>
 	<classpathentry kind="lib" path="/openbravo/lib/build/servlet-api.jar"/>
 	<classpathentry kind="output" path="build/classes"/>
Binary file src-util/buildvalidation/build/classes/org/openbravo/buildvalidation/CheckUpdateConnectionPoolMerge.class has changed
Binary file src-util/buildvalidation/build/classes/org/openbravo/buildvalidation/CheckUpdateConnectionPoolMergeData.class has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src-util/buildvalidation/src/org/openbravo/buildvalidation/CheckUpdateConnectionPoolMerge.java	Thu Aug 06 09:46:54 2015 +0200
@@ -0,0 +1,305 @@
+/*
+ *************************************************************************
+ * The contents of this file are subject to the Openbravo  Public  License
+ * Version  1.1  (the  "License"),  being   the  Mozilla   Public  License
+ * Version 1.1  with a permitted attribution clause; you may not  use this
+ * file except in compliance with the License. You  may  obtain  a copy of
+ * the License at http://www.openbravo.com/legal/license.html
+ * Software distributed under the License  is  distributed  on  an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific  language  governing  rights  and  limitations
+ * under the License.
+ * The Original Code is Openbravo ERP.
+ * The Initial Developer of the Original Code is Openbravo SLU
+ * All portions are Copyright (C) 2015 Openbravo SLU
+ * All Rights Reserved.
+ * Contributor(s):  ______________________________________.
+ ************************************************************************
+ */
+
+package org.openbravo.buildvalidation;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.log4j.Logger;
+import org.openbravo.buildvalidation.BuildValidation;
+import org.openbravo.database.ConnectionProvider;
+
+/**
+ * This build validation prevents a bad behaviour updating to PR15Q4 by taking into account the
+ * following scenarios: 
+ *      - Update from < 3.0PR15Q4 using defaults connection pools.
+ *      - Update from < 3.0PR15Q4 using Apache JDBC Connection Pool module or another external
+ *      connection pool.
+ * 
+ * It must be ensured that if an enviroment did not use "Apache JDBC Connection Pool" module, it
+ * must continue without using the connection pool. On the other hand, environments that used the
+ * module continue to use the Apache JDBC Connection pool. It will try to retrieve the configuration
+ * of the module. The new instances will start using the new connection pool.
+ *
+ * @author inigo.sanchez
+ *
+ */
+public class CheckUpdateConnectionPoolMerge extends BuildValidation {
+
+  private final static String PROPERTY_CONNECTION_POOL = "db.externalPoolClassName";
+  private final static String PATH_CONNECTIONPOOL_PROPERTIES = "/WebContent/WEB-INF/connectionPool.properties";
+  private final static String PATH_OPENBRAVO_PROPERTIES = "/config/Openbravo.properties";
+  private final static String TARGET_VERSION = "1.0.27056";
+  private final static String PREFIX_POOL_PROPERTIES = "db.pool.";
+  private final static String SUFFIX_AUX = "_aux";
+
+  private static Logger log = Logger.getLogger(CheckUpdateConnectionPoolMerge.class);
+  private Properties obProperties = null;
+
+  @Override
+  public List<String> execute() {
+    ConnectionProvider cp = getConnectionProvider();
+    try {
+      String versionOfModule = CheckUpdateConnectionPoolMergeData.versionOfConnectionPoolModule(cp);
+
+      if (versionOfModule == null || isNecessaryMerge(versionOfModule, TARGET_VERSION)) {
+        String obDir = getSourcePathFromOBProperties();
+        String openbravoPropertiesPath = obDir + PATH_OPENBRAVO_PROPERTIES;
+
+        // It must be ensured that if an enviroment did not use "Apache JDBC Connection Pool"
+        // module, it must continue without using the connection pool. In that case remove value of
+        // the property.
+        if (versionOfModule == null) {
+          File fileW = new File(openbravoPropertiesPath);
+          // removes value of property that merge in Openbravo.properties
+          replaceProperty(fileW, openbravoPropertiesPath + SUFFIX_AUX, PROPERTY_CONNECTION_POOL, "=");
+          try {
+            fileW.delete();
+            File fileAux = new File(openbravoPropertiesPath + SUFFIX_AUX);
+            fileAux.renameTo(new File(openbravoPropertiesPath));
+          } catch (Exception ex) {
+            log.error("Error renaming/deleting Openbravo.properties", ex);
+          }
+          log.info("Removed value of " + PROPERTY_CONNECTION_POOL + " property.");
+
+        } else {
+          // Environments that previously used the connection pool module. It will try to retrieve
+          // the configuration of the module. It is necessary to merge connectionPool.properties
+          String connectionPoolPropertiesPath = obDir + PATH_CONNECTIONPOOL_PROPERTIES;
+          mergeOpenbravoPropertiesConnectionPool(openbravoPropertiesPath,
+              connectionPoolPropertiesPath);
+        }
+      }
+    } catch (Exception e) {
+      handleError(e);
+    }
+    return new ArrayList<String>();
+  }
+
+  /**
+   * Checks version of the module.
+   *
+   * @return true if it is necessary to merge.
+   */
+  private boolean isNecessaryMerge(String version, String targetVersion) {
+    String[] targetNumberVersion = targetVersion.split(".");
+    String[] numberVersion = version.split(".");
+
+    // if version is equal or lower than TARGET_VERSION, it must be merged
+    for (int i = 0; i < numberVersion.length; i++) {
+      if (Integer.parseInt(numberVersion[i]) > Integer.parseInt(targetNumberVersion[i])) {
+        return false;
+      } else if (Integer.parseInt(numberVersion[i]) < Integer.parseInt(targetNumberVersion[i])) {
+        return true;
+      }
+    }
+    // here it is same version than target version or at least smaller
+    return true;
+  }
+
+  /**
+   * When updating core and it is include Apache JDBC Connection Pool into distribution in some
+   * cases is necessary to update Openbravo.properties taking into account
+   * connectionPool.properties.
+   *
+   * This connectionPool.properties file exists in instances with Apache JDBC Connection Pool
+   * module.
+   *
+   * @return false in case no changes were needed, true in case the merge includes some changes
+   */
+  private static boolean mergeOpenbravoPropertiesConnectionPool(String OpenbravoPropertiesPath,
+      String connectionPoolPath) {
+    Properties openbravoProperties = new Properties();
+    Properties connectionPoolProperties = new Properties();
+    try {
+      // load both files
+      openbravoProperties.load(new FileInputStream(OpenbravoPropertiesPath));
+      connectionPoolProperties.load(new FileInputStream(connectionPoolPath));
+
+      Enumeration<?> propertiesConnectionPool = connectionPoolProperties.propertyNames();
+      while (propertiesConnectionPool.hasMoreElements()) {
+        String propName = (String) propertiesConnectionPool.nextElement();
+        String origValue = openbravoProperties.getProperty(PREFIX_POOL_PROPERTIES + propName);
+        String connectionPoolValue = connectionPoolProperties.getProperty(propName);
+
+        // try to get original value for new property, if it does not exist add it to original
+        // properties with its default value
+        if (origValue == null) {
+          addNewProperty(OpenbravoPropertiesPath, PREFIX_POOL_PROPERTIES + propName,
+              connectionPoolValue);
+          openbravoProperties.setProperty(PREFIX_POOL_PROPERTIES + propName, connectionPoolValue);
+        } else {
+          // replace value in Openbravo.properties by value in connectionPool.properties
+          try {
+            File fileW = new File(OpenbravoPropertiesPath);
+
+            if (!(origValue.equals(connectionPoolValue))) {
+              replaceProperty(fileW, OpenbravoPropertiesPath + SUFFIX_AUX, PREFIX_POOL_PROPERTIES
+                  + propName, "=" + connectionPoolValue);
+              try {
+                fileW.delete();
+                File fileAux = new File(OpenbravoPropertiesPath + SUFFIX_AUX);
+                fileAux.renameTo(new File(OpenbravoPropertiesPath));
+              } catch (Exception ex) {
+                log.error("Error renaming/deleting Openbravo.properties", ex);
+              }
+            }
+          } catch (Exception e) {
+            log.error("Error read/write Openbravo.properties", e);
+          }
+        }
+      }
+    } catch (Exception notFoundConnectionPoolProperties) {
+      return false;
+    }
+    log.info("Merged connection pool properties with Openbravo.properties file.");
+    return true;
+  }
+
+  /**
+   * Adds a new property in a merge of properties file.
+   * 
+   * Extract from original method in org.openbravo.erpCommon.utility.Utility.java. It is necessary
+   * because build validations can not work with external methods.
+   *
+   * @param pathFile
+   *          properties file path
+   * @param propertyName
+   *          new property to add
+   * @param value
+   *          new value to add
+   */
+  private static void addNewProperty(String pathFile, String propertyName, String value) {
+    File fileW = new File(pathFile);
+    try {
+      BufferedWriter bw = new BufferedWriter(new FileWriter(fileW, true));
+      bw.write("\n" + propertyName + "=" + value + "\n");
+      bw.close();
+    } catch (Exception e1) {
+      log.error("Exception reading/writing file: ", e1);
+    }
+  }
+
+  /**
+   * Replaces a value changeOption in addressFilePath. FileR is used to check that exists
+   * searchOption with different value.
+   * 
+   * Extract from original method in org.openbravo.configuration.ConfigurationApp.java. It is
+   * necessary because build validations can not work with external methods.
+   *
+   * @param fileR
+   *          old file to read
+   * @param addressFilePath
+   *          file to write new property
+   * @param searchOption
+   *          Prefix to search
+   * @param changeOption
+   *          Value to write in addressFilePath
+   */
+  private static void replaceProperty(File fileR, String addressFilePath, String searchOption,
+      String changeOption) throws Exception {
+    boolean isFound = false;
+    FileReader fr = new FileReader(fileR);
+    BufferedReader br = new BufferedReader(fr);
+    // auxiliary file to rewrite
+    File fileW = new File(addressFilePath);
+    FileWriter fw = new FileWriter(fileW);
+    // data for restore
+    String line;
+    while ((line = br.readLine()) != null) {
+      if (line.indexOf(searchOption) == 0) {
+        // Replace new option
+        line = line.replace(line, searchOption + changeOption);
+        isFound = true;
+      }
+      fw.write(line + "\n");
+    }
+    if (!isFound) {
+      fw.write(searchOption + changeOption);
+    }
+    fr.close();
+    fw.close();
+    br.close();
+  }
+
+  /**
+   * Searches an option in filePath file and returns the value of searchOption.
+   * 
+   * Extract from original method in org.openbravo.configuration.ConfigurationApp.java. It is
+   * necessary because build validations can not work with external methods.
+   *
+   * @param filePath
+   *          Path of file
+   * @param searchOption
+   *          Prefix of property to search
+   * @return valueFound Value found
+   */
+  private static String searchProperty(File filePath, String searchOption) {
+    String valueFound = "";
+    try {
+      FileReader fr = new FileReader(filePath);
+      BufferedReader br = new BufferedReader(fr);
+      String line;
+      while ((line = br.readLine()) != null) {
+        if (line.indexOf(searchOption) == 0) {
+          valueFound = line.substring(searchOption.length() + 1);
+          break;
+        }
+      }
+      fr.close();
+      br.close();
+    } catch (Exception e) {
+      log.error("Exception searching a property: ", e);
+    }
+    return valueFound;
+  }
+
+  /**
+   * Gets source.path property from Openbravo.properties file
+   * 
+   */
+  private String getSourcePathFromOBProperties() {
+    // get the location of the current class file
+    final URL url = this.getClass().getResource(getClass().getSimpleName() + ".class");
+    File f = new File(url.getPath());
+    File propertiesFile = null;
+    while (f.getParentFile() != null && f.getParentFile().exists()) {
+      f = f.getParentFile();
+      final File configDirectory = new File(f, "config");
+      if (configDirectory.exists()) {
+        propertiesFile = new File(configDirectory, "Openbravo.properties");
+        if (propertiesFile.exists()) {
+          // found it and break
+          break;
+        }
+      }
+    }
+    return searchProperty(propertiesFile, "source.path");
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src-util/buildvalidation/src/org/openbravo/buildvalidation/CheckUpdateConnectionPoolMerge_data.xsql	Thu Aug 06 09:46:54 2015 +0200
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ *************************************************************************
+ * The contents of this file are subject to the Openbravo  Public  License
+ * Version  1.1  (the  "License"),  being   the  Mozilla   Public  License
+ * Version 1.1  with a permitted attribution clause; you may not  use this
+ * file except in compliance with the License. You  may  obtain  a copy of
+ * the License at http://www.openbravo.com/legal/license.html
+ * Software distributed under the License  is  distributed  on  an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific  language  governing  rights  and  limitations
+ * under the License.
+ * The Original Code is Openbravo ERP.
+ * The Initial Developer of the Original Code is Openbravo SLU
+ * All portions are Copyright (C) 2015 Openbravo SLU
+ * All Rights Reserved.
+ * Contributor(s):  ______________________________________.
+ ************************************************************************
+-->
+
+
+<SqlClass name="CheckUpdateConnectionPoolMergeData" package="org.openbravo.buildvalidation">   
+   <SqlMethod name="versionOfConnectionPoolModule" type="preparedStatement" return="string">
+      <SqlMethodComment>This query get the version of Apache External Connection Pool module</SqlMethodComment>
+      <Sql><![CDATA[
+         SELECT version
+            FROM ad_module
+            WHERE ad_module_id = '8A098711BB324335A19833286BDB093D'
+          ]]>
+      </Sql>
+  </SqlMethod>
+</SqlClass>
--- a/src-wad/.classpath	Wed Aug 05 12:33:11 2015 +0200
+++ b/src-wad/.classpath	Thu Aug 06 09:46:54 2015 +0200
@@ -5,8 +5,6 @@
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/OpenbravoCore"/>
 	<classpathentry kind="lib" path="/openbravo/lib/runtime/xercesImpl.jar"/>
-	<classpathentry kind="lib" path="/openbravo/lib/runtime/ojdbc6.jar"/>
-	<classpathentry kind="lib" path="/openbravo/lib/runtime/postgresql-9.0-801.jdbc4.jar"/>
 	<classpathentry kind="lib" path="/openbravo/lib/runtime/log4j-1.2.16.jar"/>
 	<classpathentry kind="lib" path="/openbravo/lib/runtime/commons-collections-3.2.1.jar"/>
 	<classpathentry kind="lib" path="/openbravo/lib/build/servlet-api.jar"/>
--- a/src/org/openbravo/base/model/ModelProvider.java	Wed Aug 05 12:33:11 2015 +0200
+++ b/src/org/openbravo/base/model/ModelProvider.java	Thu Aug 06 09:46:54 2015 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2008-2014 Openbravo SLU 
+ * All portions are Copyright (C) 2008-2015 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -37,6 +37,7 @@
 import org.hibernate.classic.Session;
 import org.hibernate.criterion.Order;
 import org.hibernate.criterion.Restrictions;
+import org.openbravo.base.ConnectionProviderContextListener;
 import org.openbravo.base.exception.OBException;
 import org.openbravo.base.model.domaintype.BaseDomainType;
 import org.openbravo.base.model.domaintype.ForeignKeyDomainType;
@@ -353,8 +354,14 @@
   private void initializeReferenceClasses(ModelSessionFactoryController sessionFactoryController) {
     ConnectionProviderImpl con = null;
     Connection connection = null;
+    boolean createdNewPool = false;
     try {
-      con = new ConnectionProviderImpl(OBPropertiesProvider.getInstance().getOpenbravoProperties());
+      con = (ConnectionProviderImpl) ConnectionProviderContextListener.getPool();
+      if (con == null) {
+        con = new ConnectionProviderImpl(OBPropertiesProvider.getInstance()
+            .getOpenbravoProperties());
+        createdNewPool = true;
+      }
       connection = con.getConnection();
       PreparedStatement ps = null;
       try {
@@ -387,7 +394,7 @@
         // do nothing
       }
       try {
-        if (con != null) {
+        if (con != null && createdNewPool) {
           con.destroy();
         }
       } catch (Exception e) {
--- a/src/org/openbravo/dal/core/SessionHandler.java	Wed Aug 05 12:33:11 2015 +0200
+++ b/src/org/openbravo/dal/core/SessionHandler.java	Thu Aug 06 09:46:54 2015 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2008-2014 Openbravo SLU 
+ * All portions are Copyright (C) 2008-2015 Openbravo SLU
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -27,6 +27,7 @@
 import org.hibernate.FlushMode;
 import org.hibernate.Query;
 import org.hibernate.Session;
+import org.hibernate.SessionFactory;
 import org.hibernate.Transaction;
 import org.openbravo.base.model.Entity;
 import org.openbravo.base.provider.OBNotSingleton;
@@ -56,7 +57,7 @@
   {
     String poolClassName = OBPropertiesProvider.getInstance().getOpenbravoProperties()
         .getProperty("db.externalPoolClassName");
-    if (poolClassName != null) {
+    if (poolClassName != null && !"".equals(poolClassName)) {
       try {
         externalConnectionPool = ExternalConnectionPool.getInstance(poolClassName);
       } catch (Throwable e) {
@@ -136,19 +137,26 @@
   }
 
   protected Session createSession() {
+    SessionFactory sf = SessionFactoryController.getInstance().getSessionFactory();
     // Checks if the session connection has to be obtained using an external connection pool
     if (externalConnectionPool != null && this.getConnection() == null) {
       Connection externalConnection = externalConnectionPool.getConnection();
+      try {
+        // Autocommit is disabled because DAL is taking into account his logical and DAL is setting
+        // autoCommint to false to maintain transactional way of working.
+        externalConnection.setAutoCommit(false);
+      } catch (SQLException e) {
+        log.error("Error setting this connection's to auto-commit mode", e);
+      }
       this.setConnection(externalConnection);
     }
     if (this.connection != null) {
       // If the connection has been obtained using an external connection pool it is passed to
       // openSession, to prevent a new connection to be created using the Hibernate default
       // connection pool
-      return SessionFactoryController.getInstance().getSessionFactory()
-          .openSession(this.connection);
+      return sf.openSession(this.connection);
     } else {
-      return SessionFactoryController.getInstance().getSessionFactory().openSession();
+      return sf.openSession();
     }
   }
 
--- a/src/org/openbravo/erpCommon/ad_forms/ModuleManagement.java	Wed Aug 05 12:33:11 2015 +0200
+++ b/src/org/openbravo/erpCommon/ad_forms/ModuleManagement.java	Thu Aug 06 09:46:54 2015 +0200
@@ -2705,6 +2705,12 @@
       if (mmodel.exists()) {
         modelFiles.add(mmodel);
       }
+
+      // add columns defined in external modules
+      File modifiedTablesModel = new File(moduleFile, "src-db/database/model/modifiedTables");
+      if (modifiedTablesModel.exists()) {
+        modelFiles.add(modifiedTablesModel);
+      }
     }
     Database db = DatabaseUtils.readDatabase(modelFiles.toArray(new File[1]));
 
--- a/src/org/openbravo/erpCommon/utility/Utility.java	Wed Aug 05 12:33:11 2015 +0200
+++ b/src/org/openbravo/erpCommon/utility/Utility.java	Thu Aug 06 09:46:54 2015 +0200
@@ -1911,17 +1911,44 @@
       // properties with its default value
       if (origValue == null) {
         String newValue = newOBProperties.getProperty(propName);
+        addNewProperty(originalFile, propName, newValue, !modified);
         origOBProperties.setProperty(propName, newValue);
         modified = true;
       }
     }
 
-    // save original file only in case it has modifications
-    if (modified) {
-      origOBProperties
-          .store(new FileOutputStream(originalFile), "Automatically updated properties");
+    return modified;
+  }
+
+  /**
+   * Adds a new property in a merge of properties file
+   *
+   * @param pathFile
+   *          properties file path
+   * @param propertyName
+   *          new property to add
+   * @param value
+   *          new value to add
+   * @param firstUpdate
+   *          true in case that this new property is the first to change. In this case add a header
+   *          with the date
+   */
+  private static void addNewProperty(String pathFile, String propertyName, String value,
+      boolean firstUpdate) {
+    File fileW = new File(pathFile);
+    try {
+      BufferedWriter bw = new BufferedWriter(new FileWriter(fileW, true));
+      if (firstUpdate) {
+        bw.write("\n#################################\n");
+        bw.write("# Merge properties              #\n");
+        bw.write("# " + new Date().toString() + " #\n");
+        bw.write("#################################\n");
+      }
+      bw.write(propertyName + "=" + value + "\n");
+      bw.close();
+    } catch (Exception e1) {
+      log4j.error("Exception reading/writing file: ", e1);
     }
-    return modified;
   }
 
   /**