Hi,
If a Thread is performing IO on a non-NIO socket (not created from a NIO channel) then an attempt to interrupt the thread (via Thread.interrupt()) fails. I have noticed that when I swap out the code in:
net.sourceforge.jtds.jdbc.SharedSocket#private Socket createSocketForJDBC3(...) { ...
to create the Socket from a call to:
SocketChannel socketChannel = SocketChannel.open((SocketAddress)address);
instead of using the reflection code (that it currently uses as of jtds-1.2.2) then interrupted threads terminate immediately.
I haven't done much diagnostics to see if the server still thinks someone's connected for those connections from Terminated threads (that don't terminate on jdk1.5.0_10), but I read in the Thread documentation that the channel will be properly closed. Even if somehow it's being closed by connection pool won't let me reclaim the resources! (the tomcat-specific-dbcp connection pool from dbcp), however the more significant point is whether the DB receives a connection closed event on the socket so the query can be halted.
Is there some reason why channels aren't being used?
The relevant code could look like (using a system switch passed in on the command line as -DjTDS.useChannels
Socket socket = null;
if (Boolean.getBoolean("jTDS.useChannels")) {
//$$$MPG Try Channels
try {
Constructor inetSocketAddressCtor = Class.forName("java.net.InetSocketAddress")
.getConstructor(new Class[] {String.class, int.class});
Object address = inetSocketAddressCtor.newInstance(
new Object[] {host, new Integer(port)});
SocketChannel socketChannel = SocketChannel.open((SocketAddress)address);
socket = socketChannel.socket();
}
catch (Exception e) {
e.printStackTrace();
socket = null;
}
}
//$$$MPG if the socket is null, use the original code
if (socket == null) {
// ... the old, non-nio code can stay here
}
return socket;
Anonymous
Using any NIO-classes would currently break backward compatibility with Java 1.3. Maybe that's something we should consider for jTDS 2.0 which will require Java 5, nevertheless.