title: ORA-01017: invalid username/password; logon denied when using wss4j
body: <p>I have many tests which access our Oracle DB without a problem, however when I run these tests along with other tests in our codebase which use a keystore, the tests that interact with the DB are no longer able to connect.  Here is the exception they get:</p>
  
  <blockquote>
    <p>Caused by: java.sql.SQLException: ORA-01017: invalid username/password; logon denied
        at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:439)
        at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:388)
        at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:381)
        at oracle.jdbc.driver.T4CTTIfun.processError(T4CTTIfun.java:564)
        at oracle.jdbc.driver.T4CTTIoauthenticate.processError(T4CTTIoauthenticate.java:431)
        at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:436)
        at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:186)
        at oracle.jdbc.driver.T4CTTIoauthenticate.doOAUTH(T4CTTIoauthenticate.java:366)
        at oracle.jdbc.driver.T4CTTIoauthenticate.doOAUTH(T4CTTIoauthenticate.java:752)
        at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:359)
        at oracle.jdbc.driver.PhysicalConnection.(PhysicalConnection.java:531)
        at oracle.jdbc.driver.T4CConnection.(T4CConnection.java:221)
        at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32)
        at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:503)
        at org.apache.commons.dbcp.DriverConnectionFactory.createConnection(DriverConnectionFactory.java:37)
        at org.apache.commons.dbcp.PoolableConnectionFactory.makeObject(PoolableConnectionFactory.java:290)
        at org.apache.commons.dbcp.BasicDataSource.validateConnectionFactory(BasicDataSource.java:877)
        at org.apache.commons.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:851)
        ... 68 more</p>
  </blockquote>
  
  <p>Obviously the username and password are still correct.  I'm having a really hard time figuring out what in our code is causing the connection to fail, and I don't really know how to debug what's happening when the Oracle driver tries to connect.  I'm using the Oracle thin driver with Oracle 11g.  We use Spring, Hibernate, and the Apache Commons DBCP.  It seems like the driver is maybe trying to establish an SSL connection to the DB?  I'm not sure though.  I seem to remember a very similar issue with SQL Server when we were still using that, at the time I just ignored it.  Right now we run the tests that interact with the keystore in a separate batch and JVM.</p>
  
  <p>Any help would be greatly appreciated.</p>
  
  <p><strong>UPDATED</strong></p>
  
  <p>I did a bunch more debugging and finally traced this down to our use of the wss4j library  (version 1.5.9) via Spring-WS.  Eventually the WSSConfig class gets to a set of code that does this:</p>
  
  <pre><code>int ret = 0;
  for (int i = 0; i &lt; provs.length; i++) {
      if ("SUN".equals(provs[i].getName())
          || "IBMJCE".equals(provs[i].getName())) {
          ret =
              java.security.Security.insertProviderAt(
                  (java.security.Provider) c.newInstance(), i + 2
              );
          break;
      }
  }
  </code></pre>
  
  <p>Immediately after this code my connections to Oracle stop working.  It looks like when the insertProviderAt method is called using a bouncy castle provider my Oracle connection starts failing.  Any ideas?</p>
  
  <p><strong>Minimal Test Case</strong></p>
  
  <p>The first connection attempt succeeds, but the second attempt fails.</p>
  
  <pre><code>Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@server/servicename", "username", "password");
  conn.prepareStatement("select * from dual").getResultSet();
  conn.close();
  org.apache.ws.security.WSSConfig.getDefaultWSConfig();
  conn = DriverManager.getConnection("jdbc:oracle:thin:server/servicename", "username", "password");
  conn.prepareStatement("select * from dual").getResultSet();
  conn.close();
  </code></pre>
  
  <p><strong>WSSConfig Initialize Method</strong></p>
  
  <pre><code>private synchronized void
      staticInit() {
          if (!staticallyInitialized) {
              org.apache.xml.security.Init.init();
              if (addJceProviders) {
                  /*
                   * The last provider added has precedence, that is if JuiCE can be added
                   * then WSS4J uses this provider.
                   */
                  addJceProvider("BC", "org.bouncycastle.jce.provider.BouncyCastleProvider");
                  addJceProvider("JuiCE", "org.apache.security.juice.provider.JuiCEProviderOpenSSL");
              }
              Transform.init();
              try {
                  Transform.register(
                      STRTransform.implementedTransformURI,
                      "org.apache.ws.security.transform.STRTransform"
                  );
              } catch (Exception ex) {
                  if (log.isDebugEnabled()) {
                      log.debug(ex.getMessage(), ex);
                  }
              }
              staticallyInitialized = true;
          }
      }
  </code></pre>