Menu

HA-JDBC with Oracle

Help
2009-03-02
2012-09-28
  • Mark Pardijs

    Mark Pardijs - 2009-03-02

    I have some trouble using HA-JDBC with an Oracle database

    When I use the following ha-jdbc-cluster.xml config:

    <pre>
    <ha-jdbc>
    <sync id="passive" class="net.sf.hajdbc.sync.PassiveSynchronizationStrategy"/>
    <cluster balancer="simple" dialect="oracle" default-sync="net.sf.hajdbc.sync.PassiveSynchronizationStrategy"
    transaction-mode="parallel" meta-data-cache="none">
    <datasource id="database1">
    <driver>oracle.jdbc.pool.OracleConnectionPoolDataSource</driver>
    <url>jdbc:oracle:thin:@server:1522:db1</url>
    <user>credential</user>
    <password>credential</password>
    </datasource>
    </cluster>
    </ha-jdbc>
    </pre>

    I got the following exception:
    <pre>
    Caused by: org.jibx.runtime.JiBXException: Expected "cluster" end tag, found "datasource" start tag (line 5, col 17)
    at org.jibx.runtime.impl.UnmarshallingContext.parsePastCurrentEndTag(UnmarshallingContext.java:800)
    at net.sf.hajdbc.sql.DriverDatabaseCluster.JiBX_binding_driver_unmarshal_2_0(DriverDatabaseCluster.java)
    at net.sf.hajdbc.sql.JiBX_binding_driverDriverDatabaseCluster_access.unmarshal()
    at org.jibx.runtime.impl.UnmarshallingContext.unmarshalElement(UnmarshallingContext.java:2773)
    at net.sf.hajdbc.sql.AbstractDatabaseCluster.preRegister(AbstractDatabaseCluster.java:1045)
    at com.sun.jmx.mbeanserver.BaseMetaDataImpl.preRegisterInvoker(BaseMetaDataImpl.java:83)
    </pre>

    Same with <pool-datasource> instead of <datasource>

    The following config didn't work at the first time:

    <pre>
    <ha-jdbc>
    <sync id="passive" class="net.sf.hajdbc.sync.PassiveSynchronizationStrategy"/>
    <cluster balancer="simple" dialect="oracle" default-sync="net.sf.hajdbc.sync.PassiveSynchronizationStrategy"
    transaction-mode="parallel" meta-data-cache="none">
    <database id="database1">
    <driver>oracle.jdbc.driver.OracleDriver</driver>
    <url>jdbc:oracle:thin:@server:1522:db1</url>
    <user>credential</user>
    <password>credential</password>
    </database>
    </cluster>
    </ha-jdbc>
    </pre>

    Somehow the user and password property where not stored in the map where all the database are kept in, so when it tried to invoke the driver its properties where empty.
    I had to get the properties from the database object directly to make it work:

    I had to add to DatabaseDriver.java:

    <pre>
    this.setProperties(properties);
    </pre>

    in the connect method,

    I changed Driver.java to this:

    <pre>
    public Connection invoke(Database<java.sql.Driver> database, java.sql.Driver driver) throws SQLException
    {
    String url = ((DriverDatabase) database).getUrl();

                // Oracle properties (user and password) are not properly stored in the map where it's coming from
                // so get them from the DriverDatabase object
                Properties oracleProperties = ((DriverDatabase) database).getProperties();
                logger.info(&quot;Loading database &quot; + database.getId());
                Connection connection =  driver.connect(url, oracleProperties);
                return connection;
            }
    

    </pre>

    Someone else who got this (i.e. an Oracle database) to work without additional source code adjustments?

     
    • Mark Pardijs

      Mark Pardijs - 2009-03-12

      Yes the user exists.

      I actually now have the same user and pass in my .xml config file and in my resin.conf.

      Since (as a tryout) I adjusted the source code to always use the username and pass provided in the xml config file I know this user should work.

      Stacktrace:

      java.sql.SQLException: invalid arguments in call
      at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
      at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146)
      at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:208)
      at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:236)
      at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:414)
      at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:165)
      at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:35)
      at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:801)
      at net.sf.hajdbc.sql.Driver$1.invoke(Driver.java:96)
      at net.sf.hajdbc.sql.Driver$1.invoke(Driver.java:91)
      at net.sf.hajdbc.sql.DatabaseWriteInvocationStrategy$1.call(DatabaseWriteInvocationStrategy.java:92)
      at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
      at java.util.concurrent.FutureTask.run(FutureTask.java:138)
      at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
      at java.lang.Thread.run(Thread.java:619)

       
      • Paul Ferraro

        Paul Ferraro - 2009-03-17

        Can you add some logging to the net.sf.hajdbc.sql.Driver.connect() method to show what values are getting passed to the OracleDriver.connect()?

         
    • Mark Pardijs

      Mark Pardijs - 2009-03-02

      By the way, this is with ha-jdbc-2.0.15-jdk1.5 and Jibx-run 1.6

       
    • Paul Ferraro

      Paul Ferraro - 2009-03-02
       
      • Mark Pardijs

        Mark Pardijs - 2009-03-02

        Thanks for the reply, it's clear now!

         
    • Paul Ferraro

      Paul Ferraro - 2009-03-02

      Also you can only use the <datasource> based config if your application obtains connections using HA-JDBC's DataSource implementation. Likewise, <pool-datasource> based config is only relevant for application servers that use HA-JDBC's ConnectionPoolDataSource implementation for connection pooling.

      If your application uses HA-JDBC's JDBC driver in some form, either directly or referenced from some wrapper DataSource, you need to use the <database> based config. This is the case with your setup.

       
    • Mark Pardijs

      Mark Pardijs - 2009-03-06

      Still not working as I expected. The error I keep getting is invalid arguments in call, as if I didn't specify a username and password.

      I have specified the user and password in the cluster.xml config file:

      <ha-jdbc>
      <cluster balancer="round-robin" dialect="Oracle"
      default-sync="net.sf.hajdbc.sync.DifferentialSynchronizationStrategy"
      transaction-mode="parallel" meta-data-cache="none">

          &lt;database id=&quot;database1&quot; weight=&quot;1&quot;&gt;
              &lt;driver&gt;oracle.jdbc.driver.OracleDriver&lt;/driver&gt;
              &lt;url&gt;jdbc:oracle:thin:@dbserver:1522:db1&lt;/url&gt;
              &lt;user&gt;his0&lt;/user&gt;
              &lt;password&gt;his0&lt;/password&gt;
          &lt;/database&gt;
      
      &lt;/cluster&gt;
      

      </ha-jdbc>

      , and in my Resin config file

      <resource-ref>
      <res-ref-name>jdbc/ha-jdbc</res-ref-name>
      <res-type>javax.sql.DataSource</res-type>

                      &lt;init-param driver-name=&quot;net.sf.hajdbc.sql.Driver&quot;/&gt;
                      &lt;init-param url=&quot;jdbc:ha-jdbc:cluster&quot;/&gt;
                      &lt;init-param user=&quot;mark&quot;/&gt;     
                      &lt;init-param password=&quot;mark&quot;/&gt;
      
              &lt;/resource-ref&gt;
      

      Still, when trying to connect, I got the 'Invalid arguments in call' exception...

       
    • Paul Ferraro

      Paul Ferraro - 2009-03-06

      Are you certain that the "mark" user exists on each database in your cluster? Can you attach the stack trace?

       
    • Mark Pardijs

      Mark Pardijs - 2009-03-17

      Any update on this?

       

Log in to post a comment.