title: Spring Boot with multiple datasources Oracle and H2
body: <p>I develop a spring boot RestController for my angular Project and encountered a problem. In my logic for the rest-service I used two different databases to get data from.</p>
  
  <p>Here you can see the datasource configuration:</p>
  
  <p>[application.properties]</p>
  
  <pre><code>#datasource1
  spring.datasource.url=[url]
  spring.datasource.username=[username]
  spring.datasource.password=[password]
  spring.datasource.driverClassName=org.h2.Driver
  
  #datasource2
  spring.secondDatasource.url=[url]
  spring.secondDatasource.username=[username]
  spring.secondDatasource.password=[password]
  spring.secondDatasource.driverClassName=oracle.jdbc.OracleDriver
  </code></pre>
  
  <p>[DatasourceConfig.java]
  </p>
  
  <pre><code>@Bean
  @Primary
  @ConfigurationProperties(prefix="spring.datasource")
  public DataSource h2DataSource() {
      return DataSourceBuilder.create().build();
  }
  
  @Bean
  @ConfigurationProperties(prefix="spring.secondDatasource")
  public DataSource oracleDataSource() {
      return DataSourceBuilder.create().build();
  }
  </code></pre>
  
  <p>Logging output: (No Exceptions are ever thrown for this problem)</p>
  
  <pre><code>...
  2016-11-22 13:20:25.853 [INFO ] 1  [main] d.b.s.Application : Started Application in 7.757 seconds (JVM running for 12.515)
  2016-11-22 13:20:31.731 [INFO ] 62 [http-nio-8080-exec-1] o.s.w.s.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
  2016-11-22 13:20:31.757 [INFO ] 62 [http-nio-8080-exec-1] o.s.w.s.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 26 ms
  2016-11-22 13:20:34.984 [INFO ] 65 [http-nio-8080-exec-5] d.b.s.r.RESTclient : /rest/getMyData
  2016-11-22 13:20:34.992 [INFO ] 63 [http-nio-8080-exec-2] d.b.s.r.RESTclient : /rest/getMyData2
  2016-11-22 13:20:34.993 [INFO ] 69 [http-nio-8080-exec-8] d.b.s.r.RESTclient : /rest/getMyData3
  2016-11-22 13:20:35.004 [DEBUG] 65 [http-nio-8080-exec-5] d.b.s.DataSourceService : getH2Connection()
  2016-11-22 13:20:35.022 [DEBUG] 63 [http-nio-8080-exec-2] d.b.s.DataSourceService : getOracleConnection()
  2016-11-22 13:20:35.022 [DEBUG] 69 [http-nio-8080-exec-8] d.b.s.DataSourceService : getH2Connection()
  </code></pre>
  
  <p>The problem is, that every used worker thread (http-nio-8080-?, ...) for the rest-service hangs up at datasource.getConnection() in my DataSourceService. It freeze forever and waits for a Connection that can't be get.</p>
  
  <pre><code>@Service
  public class DataSourceService {
      private final DataSource h2DataSource;
      private final DataSource oracleDataSource;
  
      @Autowired
      public DataSourceService(DataSource h2DataSource, DataSource oracleDataSource) {
          this.h2DataSource = h2DataSource;
          this.oracleDataSource = oracleDataSource;
      }
  
      public Connection getH2Connection() throws SQLException {
          LoggerUtil.logDebug(getClass(), "getH2Connection()");
          return h2Connection.getConnection();
      }
  
      public Connection getOracleConnection() throws SQLException {
          LoggerUtil.logDebug(getClass(), "getOracleConnection()");
          return oracleConnection.getConnection();
      }
  }
  </code></pre>
  
  <p>The strange thing about it is, that sometimes it works without ever changed a line of code (5% of all times) and mostly (95% of all times) it hangs up.</p>
  
  <p>in my pom.xml I have following database driver dependencies:</p>
  
  <pre><code>&lt;dependency&gt;
      &lt;groupId&gt;com.oracle&lt;/groupId&gt;
      &lt;artifactId&gt;ojdbc6&lt;/artifactId&gt;
      &lt;version&gt;11.2.0.4&lt;/version&gt;
      &lt;scope&gt;runtime&lt;/scope&gt;
  &lt;/dependency&gt;
  &lt;dependency&gt;
      &lt;groupId&gt;com.h2database&lt;/groupId&gt;
      &lt;artifactId&gt;h2&lt;/artifactId&gt;
      &lt;version&gt;1.4.193&lt;/version&gt;
      &lt;scope&gt;runtime&lt;/scope&gt;
  &lt;/dependency&gt;
  </code></pre>
  
  <p>If all datasources have the same driver, this will never happen, but in combination I found this strange behavior.</p>
  
  <p>My ideas are that this only happen if the h2Database is initialized before the oracle. At this point the spring classloader loads the h2-driver classes and they will be cached. At next the oracle gets initialized and some classes are to close identical, so that some of the h2-classes are used for oracle. Because of that, the strange state of freeze is created. (perhaps also vice versa).</p>
  
  <p><strong>My question now: Why can't I use the H2 and Oracle database at the same time with Spring-boot?</strong></p>
  
  <p>EDIT:</p>
  
  <p>After some debugging I have found more informations:</p>
  
  <p>[org.apache.tomcat.jdbc.pool.ClassLoaderUtil]</p>
  
  <pre><code>Row 29:  loadClass(...)
  ...
  Row 38: return Class.forName(className, true, cl);  //className: "oracle.jdbc.OracleDriver"  cl: Launcher$AppClassLoader
  </code></pre>
  
  <p>In ClassLoaderUtil is a lookup for Driver-Class by className. The className "org.h2.Driver" can be resolved without problem, but "oracle.jdbc.OracleDriver" don't.</p>
  
  <p>After that I have made a thread dump where you can see the points for stuck. At this time there are 5 stucked threads which stucked at different positions.</p>
  
  <p>http-nio-8080-exec-2@8307 (runnable)
  (is using only oracle database)</p>
  
  <pre><code>"http-nio-8080-exec-2@8307" daemon prio=5 tid=0x40 nid=NA runnable
    java.lang.Thread.State: RUNNABLE
       blocks http-nio-8080-exec-6@8311
        at java.lang.Class.forName0(Class.java:-1)
        at java.lang.Class.forName(Class.java:348)
        at org.apache.tomcat.jdbc.pool.ClassLoaderUtil.loadClass(ClassLoaderUtil.java:38)
        at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:271)
        at org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:203)
        at org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:718)
        at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:650)
        at org.apache.tomcat.jdbc.pool.ConnectionPool.init(ConnectionPool.java:468)
        at org.apache.tomcat.jdbc.pool.ConnectionPool.&lt;init&gt;(ConnectionPool.java:143)
        at org.apache.tomcat.jdbc.pool.DataSourceProxy.pCreatePool(DataSourceProxy.java:118)
        - locked &lt;0x2139&gt; (a org.apache.tomcat.jdbc.pool.DataSource)
        at org.apache.tomcat.jdbc.pool.DataSourceProxy.createPool(DataSourceProxy.java:107)
        at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:131)
        at d.b.s.DataSourceService.getConnection(DataSourceService.java:51)                        //&lt;-- That's my package
        ...
  </code></pre>
  
  <p>http-nio-8080-exec-3@8308 (runnable)
  (comparison between oracle and h2 data)</p>
  
  <pre><code>"http-nio-8080-exec-3@8308" daemon prio=5 tid=0x41 nid=NA runnable
    java.lang.Thread.State: RUNNABLE
    at oracle.jdbc.driver.OracleDriver.&lt;clinit&gt;(OracleDriver.java:190)
    at java.lang.Class.forName0(Class.java:-1)
    at java.lang.Class.forName(Class.java:348)
    at org.apache.tomcat.jdbc.pool.ClassLoaderUtil.loadClass(ClassLoaderUtil.java:38)
    at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:271)
    at org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:203)
    at org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:718)
    at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:650)
    at org.apache.tomcat.jdbc.pool.ConnectionPool.init(ConnectionPool.java:468)
    at org.apache.tomcat.jdbc.pool.ConnectionPool.&lt;init&gt;(ConnectionPool.java:143)
    at org.apache.tomcat.jdbc.pool.DataSourceProxy.pCreatePool(DataSourceProxy.java:118)
    - locked &lt;0x213d&gt; (a org.apache.tomcat.jdbc.pool.DataSource)
    at org.apache.tomcat.jdbc.pool.DataSourceProxy.createPool(DataSourceProxy.java:107)
    at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:131)
    at d.b.s.DataSourceService.getConnection(DataSourceService.java:51)
    ...
  </code></pre>
  
  <p>http-nio-8080-exec-4@8309 (runnable)
  (comparison between oracle and h2 data)</p>
  
  <p>(same as exec-2)</p>
  
  <p>http-nio-8080-exec-5@8310 (runnable)
  (is using only h2 database)</p>
  
  <pre><code>"http-nio-8080-exec-5@8310" daemon prio=5 tid=0x43 nid=NA runnable
     java.lang.Thread.State: RUNNABLE
    at sun.reflect.GeneratedConstructorAccessor109.newInstance(Unknown Source:-1)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:-1)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at java.lang.Class.newInstance(Class.java:442)
    at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:380)
    at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)
    at java.util.ServiceLoader$1.next(ServiceLoader.java:480)
    at java.sql.DriverManager$2.run(DriverManager.java:603)
    at java.sql.DriverManager$2.run(DriverManager.java:583)
    at java.security.AccessController.doPrivileged(AccessController.java:-1)
    at java.sql.DriverManager.loadInitialDrivers(DriverManager.java:583)
    at java.sql.DriverManager.&lt;clinit&gt;(DriverManager.java:101)
    at org.h2.Driver.load(Driver.java:155)
    at org.h2.Driver.&lt;clinit&gt;(Driver.java:41)
    at java.lang.Class.forName0(Class.java:-1)
    - locked &lt;0x211b&gt; (a java.lang.Class)
    at java.lang.Class.forName(Class.java:348)
    at org.apache.tomcat.jdbc.pool.ClassLoaderUtil.loadClass(ClassLoaderUtil.java:38)
    at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:271)
    at org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:203)
    at org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:718)
    at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:650)
    at org.apache.tomcat.jdbc.pool.ConnectionPool.init(ConnectionPool.java:468)
    at org.apache.tomcat.jdbc.pool.ConnectionPool.&lt;init&gt;(ConnectionPool.java:143)
    at org.apache.tomcat.jdbc.pool.DataSourceProxy.pCreatePool(DataSourceProxy.java:118)
    at org.apache.tomcat.jdbc.pool.DataSourceProxy.createPool(DataSourceProxy.java:107)
    at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:131)
    - locked &lt;0x20e9&gt; (a org.apache.tomcat.jdbc.pool.DataSource)
    at d.b.s.DataSourceService.getConnection(DataSourceService.java:51)
    ...
  </code></pre>
  
  <p>http-nio-8080-exec-6@8311 (waiting for monitor entry)
  (comparison between oracle and h2 data)</p>
  
  <pre><code>"http-nio-8080-exec-6@8311" daemon prio=5 tid=0x44 nid=NA waiting for monitor entry
     java.lang.Thread.State: BLOCKED
   waiting for http-nio-8080-exec-2@8307 to release lock on &lt;0x2139&gt; (a org.apache.tomcat.jdbc.pool.DataSource)
    at org.apache.tomcat.jdbc.pool.DataSourceProxy.pCreatePool(DataSourceProxy.java:115)
    at org.apache.tomcat.jdbc.pool.DataSourceProxy.createPool(DataSourceProxy.java:107)
    at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:131)
    at d.b.s.DataSourceService.getConnection(DataSourceService.java:51)
    ...
  </code></pre>