web-dev-qa-db-ja.com

Tomcat 8上のjTDS JDBCドライバーでのAbstractMethodError

Tomcat 8 WebコンテナーにWebアプリ(WAR)をデプロイしています。

WARの「/ WEB-INF/lib」ディレクトリには、次のjTDS JDBCドライバが含まれています。

<dependency org="net.sourceforge.jtds" name="jtds" rev="1.3.1" />

(ファイルは:jtds-1.3.1.jar)。

これは、リソースがMETA-INF/context.xmlで定義されている方法です。

<Resource name="jdbc/jtds/sybase/somedb"
          auth="Container"
          type="javax.sql.DataSource"
          driverClassName="net.sourceforge.jtds.jdbc.Driver"
          url="jdbc:jtds:sybase://localhost:2501/somedb"
          username="someuser" password="somepassword"
/>

私のコードでは、 javax.sql.DataSource を通常の方法で取得します。

InitialContext cxt = new InitialContext();
if ( cxt == null ) {
    throw new RuntimeException("Uh oh -- no context!");
}
DataSource ds = (DataSource) cxt.lookup( lookupName );

DataSourceオブジェクトdsが予期されたタイプであることを(印刷によって)さらに確認します。

org.Apache.Tomcat.dbcp.dbcp2.BasicDataSource

…しかし、それから接続を取得しようとすると:

Connection conn = ds.getConnection();

…次のトレースが表示されます。

Java.lang.AbstractMethodError
net.sourceforge.jtds.jdbc.JtdsConnection.isValid(JtdsConnection.Java:2833)
org.Apache.Tomcat.dbcp.dbcp2.DelegatingConnection.isValid(DelegatingConnection.Java:924)
org.Apache.Tomcat.dbcp.dbcp2.PoolableConnection.validate(PoolableConnection.Java:282)
org.Apache.Tomcat.dbcp.dbcp2.PoolableConnectionFactory.validateConnection(PoolableConnectionFactory.Java:359)
org.Apache.Tomcat.dbcp.dbcp2.BasicDataSource.validateConnectionFactory(BasicDataSource.Java:2316)
org.Apache.Tomcat.dbcp.dbcp2.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.Java:2299)
org.Apache.Tomcat.dbcp.dbcp2.BasicDataSource.createDataSource(BasicDataSource.Java:2043)
org.Apache.Tomcat.dbcp.dbcp2.BasicDataSource.getConnection(BasicDataSource.Java:1543)

何ができますか?

15

追加しなければならなかったことが判明:

validationQuery="select 1"

context.xmlのResource宣言内。

これは here と記述されています(ただし、validateQueryのスペルが間違っています)。

JtdsConnectionの実装を掘り下げると、次のようになります。

/* (non-Javadoc)
 * @see Java.sql.Connection#isValid(int)
 */
public boolean isValid(int timeout) throws SQLException {
    // TODO Auto-generated method stub
    throw new AbstractMethodError();
}

これは本当に奇妙です、おそらく AbstractMethodError はコンパイラーのみによってスローされ、実装されていないメソッドは nsupportedOperationException をスローするはずです。とにかく、次の PoolableConnection のコードは、context.xmlvalidationQueryが存在するかどうかによって、状況が変化する理由を示しています。 validationQueryは、以下のメソッドのsqlStringパラメータの値として渡されます(nullを定義しない場合はvalidationQuery)。

public void More ...validate(String sql, int timeout) throws SQLException {
    ...
    if (sql == null || sql.length() == 0) {
        ...
        if (!isValid(timeout)) {
            throw new SQLException("isValid() returned false");
        }
        return;
    }
...
}

したがって、基本的にvalidationQueryが存在しない場合、isValidの場合はJtdsConnectionの接続自体の実装が参照され、AbstractMethodErrorが奇妙にスローされます。

24

私がこの問題に遭遇したとき、マーカスによる上記の答えは私にとってうまくいきました。 validationQuery設定がcontext.xmlファイルでどのように表示されるかの具体例を示すには、次のようにします。

    <Resource name="jdbc/myDB" auth="Container" type="javax.sql.DataSource"
            driverClassName="net.sourceforge.jtds.jdbc.Driver"
            url="jdbc:jtds:sqlserver://SQLSERVER01:1433/mydbname;instance=MYDBINSTANCE"
            username="dbuserid" password="dbpassword"
            validationQuery="select 1"
            />

ValidationQuery設定は、db接続の各ドライバー設定に含まれます。したがって、context.xmlファイルに別のdbエントリを追加するたびに、この設定をドライバー設定に含める必要があります。

4
Stephen

上記の答えはうまくいきます。スタンドアロンJavaアプリケーション用に設定している場合は、データソースに検証クエリを設定します。

 BasicDataSource ds = new BasicDataSource(); 

 ds.setUsername(user);
 ds.setPassword(getPassword());
 ds.setUrl(jdbcUrl);
 ds.setDriverClassName(driver);
 ds.setMaxTotal(10);
 ds.setValidationQuery("select 1"); //DBCP throws error without this query
2
Gobinath Mani