Tomcat 8上使用jTDS JDBC驱动程序的AbstractMethodError

时间:2016-12-19 22:03:18

标签: tomcat8 jtds

我正在将一个Web应用程序(WAR)部署到Tomcat 8 Web容器。

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)

是什么给出了?

3 个答案:

答案 0 :(得分:19)

原来我必须添加:

validationQuery="select 1"
<{1}}中的资源声明中的

提到here(虽然被误导为context.xml)。

深入研究validateQuery的实施情况:

JtdsConnection

这真的很奇怪,我认为AbstractMethodError只能被编译器抛出,未实现的方法应该抛出UnsupportedOperationException。无论如何,PoolableConnection中的以下代码说明了/* (non-Javadoc) * @see java.sql.Connection#isValid(int) */ public boolean isValid(int timeout) throws SQLException { // TODO Auto-generated method stub throw new AbstractMethodError(); } validationQuery的存在与否可以改变的原因:

context.xml

所以基本上如果不存在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的情况下。

答案 1 :(得分:3)

当我遇到这个问题时,Marcus上面提到的答案为我工作。给出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设置与数据库连接的每个驱动程序设置一起使用。因此,每次向context.xml文件添加另一个db条目时,都需要在驱动程序设置中包含此设置。

答案 2 :(得分:2)

上述答案有效。如果要为独立Java应用程序设置它,请在数据源中设置验证查询。

{{1}}