milesibastos / jtds Goto Github PK
View Code? Open in Web Editor NEWjTDS JDBC Driver
Home Page: http://jtds.sourceforge.net/
License: GNU Lesser General Public License v2.1
jTDS JDBC Driver
Home Page: http://jtds.sourceforge.net/
License: GNU Lesser General Public License v2.1
In High Availability setups, there are often two servers set up in a fail-over mode. This means that if one fails, the other immediately takes over. In such cases the DNS server is set up to provide two IP addresses for a DB server hostname. It is then up to the client (driver) to attempt to connect to all provided addresses before reporting a failure to connect.
This is currently not supported by jTDS, meaning it is cumbersome to use in such environments (I need to check which server is up, and change a raw IP in the settings manually). The following patch fixes this issue (however it's quite rudamentary). I'd suggest making this behavior optional, but the patch solves the issue locally for me.
diff --git a/src/main/net/sourceforge/jtds/jdbc/SharedSocket.java b/src/main/net/sourceforge/jtds/jdbc/SharedSocket.java
index d7bcd38..02caca7 100644
--- a/src/main/net/sourceforge/jtds/jdbc/SharedSocket.java
+++ b/src/main/net/sourceforge/jtds/jdbc/SharedSocket.java
@@ -25,6 +25,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
+import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.Socket;
@@ -275,18 +276,34 @@ class SharedSocket {
final String bindAddress = connection.getBindAddress();
final int loginTimeout = connection.getLoginTimeout();
- Socket socket = new Socket();
- InetSocketAddress address = new InetSocketAddress( host, port );
+ // Resolve all IPs for configured hostname
+ InetAddress[] resolvedAddresses = InetAddress.getAllByName(host);
// call Socket.bind(SocketAddress) if bindAddress parameter is set
- if( bindAddress != null && ! bindAddress.isEmpty() )
+ String lastExceptionMessage = null;
+ for (InetAddress inetAddress : resolvedAddresses)
{
- socket.bind( new InetSocketAddress( bindAddress, 0 ) );
+ try
+ {
+ Socket socket = new Socket();
+ if( bindAddress != null && ! bindAddress.isEmpty() )
+ {
+ socket.bind( new InetSocketAddress( bindAddress, 0 ) );
+ }
+
+ // Try to connect to each of the given addresses
+ InetSocketAddress address = new InetSocketAddress(inetAddress, port);
+ socket.connect(address, loginTimeout * 1000);
+ return socket;
+ }
+ catch (IOException ex)
+ {
+ // NO-OP: Continue
+ lastExceptionMessage = ex.getMessage();
+ }
}
- // establish connection
- socket.connect( address, loginTimeout * 1000 );
- return socket;
+ throw new IOException("Unable to connect to SQL server. Last error: " + lastExceptionMessage);
}
String getMAC()
I'm using jTDS in an Android application and if I interrupt a background thread running a query, it crashes my app with the following trace:
java.util.concurrent.TimeoutException: net.sourceforge.jtds.jdbc.JtdsStatement.finalize() timed out after 10 seconds
at net.sourceforge.jtds.jdbc.JtdsConnection.releaseTds(JtdsConnection.java)
at net.sourceforge.jtds.jdbc.JtdsStatement.close(JtdsStatement.java:972)
at net.sourceforge.jtds.jdbc.JtdsStatement.finalize(JtdsStatement.java:219)
at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:222)
at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:209)
at java.lang.Thread.run(Thread.java:761)
The releaseTds
method is synchronized
which makes me think this might be related to a deadlock. Or it might be waiting for some other long-running query to end.
I am relatively sure this 'issue' is my lack of understanding but hope the community may be able to help. I've clicked/read/tried every existing link on the topic without success. I have tried using different versions of jTDS though right now I'm trying with 1.3.3. Thank you in advance for any help you can provide!!
I have an Android app that connects to a SQL DB hosted on Amazon RDS. Without using SSL it works great; no problems. Below is the connection string:
Class.forName("net.sourceforge.jtds.jdbc.Driver").newInstance();
String connectionstring = "jdbc:jtds:sqlserver://" + servername + "/" + dbname + ";" +
"user=" + userid + ";password=" + pwd + ";";
Now I want to enable SSL. I made the change on the MSSQL server parameter and I am able to connect using Management Studio and .NET apps. However, I have not been able to connect via my Android app using jtds. Initially the only change I am making is to add ssl=require to the connection string.
Based on some different threads I've read I have tried adding the following line to the gradle.properties file of the project with no change:
org.gradle.jvmargs=-Djsse.enableCBCProtection=false
No matter what I do I get the same error.
"Network error IOException: SSL handshak_e aborted: ssl=0xa67a6cc0: I/O error during system call, Broken pipe"_
This is what the stacktrace prints:
W/System.err: java.sql.SQLException: Network error IOException: SSL handshake aborted: ssl=0xa67bdcc0: I/O error during system call, Broken pipe
at net.sourceforge.jtds.jdbc.JtdsConnection.(JtdsConnection.java:437)
at net.sourceforge.jtds.jdbc.Driver.connect(Driver.java:184)
at java.sql.DriverManager.getConnection(DriverManager.java:569)
at java.sql.DriverManager.getConnection(DriverManager.java:237)
W/System.err: at com.bluestarsolutions.caylix_time.DBRemote.openConnection(DBRemote.java:412)
at com.bluestarsolutions.caylix_time.DBRemote.DownloadInfo(DBRemote.java:47)
at com.bluestarsolutions.caylix_time.MainActivity$6.run(MainActivity.java:585)
at java.lang.Thread.run(Thread.java:764)
Caused by: javax.net.ssl.SSLHandshakeException: SSL handshake aborted: ssl=0xa67bdcc0: I/O error during system call, Broken pipe
W/System.err: at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:351)
at net.sourceforge.jtds.ssl.SocketFactories$TdsTlsSocketFactory.createSocket(SocketFactories.java:101)
at net.sourceforge.jtds.jdbc.SharedSocket.enableEncryption(SharedSocket.java:330)
at net.sourceforge.jtds.jdbc.TdsCore.negotiateSSL(TdsCore.java:577)
W/System.err: at net.sourceforge.jtds.jdbc.JtdsConnection.(JtdsConnection.java:365)
... 7 more
Is this an official github mirror of jTDS?
1、Sybase 15.0,using GB18030 as default charset;
2、when test Connection,get ErrorMessage:jtds Could not find a Java charset equivalent to DB charset gb18030
How To change Charsets.properties to support GB18030
When configuring query-timeout in a WildFly datasource the singleton TimerThread class is instantiated with contextClassLoader
from the first client that uses a Connection preventing garbage collect Application ClassLoader on hot redeploy the app. I think TimerThread should be initialized with library class loader as contextClassLoader
to avoid that.
Hi There,
We use jTDS to connect to SQL Server. Our setup includes using JNDI which requires the driver classes to be in Tomcat main classloader. Upon doing some profiling and memory dumps we found in at least one case a problem with jTDS lastWarning field keeping a reference to the a SQLWarning which is holding the last stack trace which is holding a reference to the Classloader. The problem seems to be that when creating a prepared statement and having an error this error is kept. Even thought the JtdsStatement calls messages.clearWarnings() this method doesn't clear the lastWarning and lastException field. Thus the entire class loader is held in memory.
The fix should be fairly easy as SQLDiagnostic.clearWarnings should reset the other variables as well.
Here is the stack from Eclipse Memory Analyzer
org.apache.tomcat.util.threads.TaskThread @ 0x17d82fc0 http-apr-8080-exec-9 Thread | 1 | 128 | 136 | 32,824
'- contextClassLoader java.net.URLClassLoader @ 0x10204ce8 | 1 | 80 | 136 | 1,155,784
'- classes java.util.Vector @ 0x103773c8 | 1 | 24 | 136 | 924,744
'- elementData java.lang.Object[2560] @ 0x1862e260 | 1 | 10,256 | 136 | 924,720
'- [283] class org.apache.tomcat.jdbc.pool.interceptor.StatementCache @ 0x107fa530 | 1 | 24 | 136 | 248
'- cacheSizeMap java.util.concurrent.ConcurrentHashMap @ 0x10b70138 | 1 | 64 | 136 | 168
'- table java.util.concurrent.ConcurrentHashMap$Node[16] @ 0x10b70178 | 1 | 80 | 136 | 104
'- [0] java.util.concurrent.ConcurrentHashMap$Node @ 0x10b701c8 | 1 | 24 | 136 | 24
'- key org.apache.tomcat.jdbc.pool.ConnectionPool @ 0x108ca8f0 | 1 | 56 | 136 | 54,472
'- idle org.apache.tomcat.jdbc.pool.FairBlockingQueue @ 0x108caee8 | 1 | 24 | 136 | 54,064
'- items java.util.LinkedList @ 0x108caf28 | 1 | 24 | 136 | 53,944
'- first java.util.LinkedList$Node @ 0x203ba2c0 | 1 | 24 | 136 | 15,584
'- item org.apache.tomcat.jdbc.pool.PooledConnection @ 0x108caf40 | 1 | 88 | 136 | 15,560
'- attributes java.util.HashMap @ 0x108e44a8 | 1 | 40 | 136 | 15,008
'- table java.util.HashMap$Node[16] @ 0x108e44d0 | 1 | 80 | 136 | 14,968
'- [5] java.util.HashMap$Node @ 0x10d328c0 | 1 | 24 | 136 | 14,840
'- value java.util.concurrent.ConcurrentHashMap @ 0x10d328d8 | 1 | 64 | 136 | 14,816
'- table java.util.concurrent.ConcurrentHashMap$Node[128] @ 0x187e06b0 | 1 | 528 | 136 | 14,752
'- [93] java.util.concurrent.ConcurrentHashMap$Node @ 0x194fcc30 | 1 | 24 | 136 | 168
'- val org.apache.tomcat.jdbc.pool.interceptor.StatementCache$CachedStatement @ 0x194fcc48 | 1 | 48 | 136 | 144
'- delegate com.sun.proxy.$Proxy98 @ 0x194a7d78 | 1 | 16 | 136 | 40
'- h org.apache.tomcat.jdbc.pool.interceptor.AbstractQueryReport$StatementProxy @ 0x194a7d88| 1 | 24 | 136 | 24
** '- delegate net.sourceforge.jtds.jdbc.JtdsPreparedStatement @ 0x194a7da0 | 1 | 120 | 136 | 71,056
'- messages net.sourceforge.jtds.jdbc.SQLDiagnostic @ 0x194b0218 | 1 | 32 | 136 | 1,048
'- lastWarning java.sql.SQLWarning @ 0x194b0238 | 1 | 40 | 136 | 1,016
'- backtrace java.lang.Object[4] @ 0x194b0260 | 1 | 32 | 136 | 800
'- [2] java.lang.Object[32] @ 0x194c0b88 ** | 1 | 144 | 136 | 144
This is an issue reported a while back on sourceforge
https://sourceforge.net/p/jtds/bugs/679/
https://stackoverflow.com/questions/8937360/wrong-data-type-returned-for-date-in-jtds-jar
I'm just creating it in case anyone wants to look at it. This issue also appears on the time type.
From my tests it looks like datetime2 and time come out as type -9 NVARCHAR
The JDBC driver should implement the isValid
method (probably using a select 1
query).
Currently, it throws a java.lang.AbstractMethodError
exception:
Exception in thread "AWT-EventQueue-0" java.lang.AbstractMethodError
at net.sourceforge.jtds.jdbc.JtdsConnection.isValid(JtdsConnection.java:2833)
Work is still being done on the Sourceforge website for the original project.
The README should be updated to reflect this.
There are many columns in the database table and SQL queries all fields, the cpu is 100% , because the initialization strategy of JtdsResultSet#columnMap is wrong.
Please see the code below
public int findColumn(String columnName) throws SQLException {
checkOpen();
if (columnMap == null) {
columnMap = new HashMap(columnCount);
} else {
Object pos = columnMap.get(columnName);// columnMap cache won't hit
if (pos != null) {
return ((Integer) pos).intValue();
}
}
// Rather than use toUpperCase()/toLowerCase(), which are costly,
// just do a sequential search. It's actually faster in most cases.
for (int i = 0; i < columnCount; i++) {
if (columns[i].name.equalsIgnoreCase(columnName)) {
columnMap.put(columnName, new Integer(i + 1)); // initialization strategy of columnMap is wrong
return i + 1;
}
}
throw new SQLException(Messages.get("error.resultset.colname", columnName), "07009");
}
I use sybase database, the query columns of sql are all uppercase, if you want to be ignore case , you need to modify it
public int findColumn(String columnName) throws SQLException {
checkOpen();
if (columnMap == null) {
// init cache
columnMap = new HashMap(columnCount);
for (int i = 0; i < columnCount; i++) {
columnMap.put(columns[i].name, new Integer(i + 1));
}
}
Object pos = columnMap.get(columnName);
if (pos != null) {
return ((Integer) pos).intValue();
}
// Rather than use toUpperCase()/toLowerCase(), which are costly,
// just do a sequential search. It's actually faster in most cases.
for (int i = 0; i < columnCount; i++) {
if (columns[i].name.equalsIgnoreCase(columnName)) {
columnMap.put(columnName, new Integer(i + 1));
return i + 1;
}
}
throw new SQLException(Messages.get("error.resultset.colname", columnName), "07009");
}
I'am getting java.sql.SQLException: Invalid JDBC escape syntax at line position 22 '=' character expected.
when using the jtds driver.
I can establish a connection with the LocalDB instance with:
jdbc:jtds:sqlserver://./myDatabase;instance=LOCALDB#xyz;namedPipe=true;User=my_user;Password=my_password
I am working with a proprietary software (Guidewire) which connects to the Server LocalDB and then starts running some SQL statements which I have no control over.
I read somewhere that the jtds driver unfortunately does not support stored procedure.
jTDS seems to report the wrong process id to the mssql server when connecting via tcp/ip. It seems to always report "123" when it should report the real process id.
not sure how to solve, a quick search leads to
http://stackoverflow.com/questions/35842/how-can-a-java-program-get-its-own-process-id
to reproduce, let jTDS connect to mssql and then use this query:
SELECT hostprocess FROM sys.sysprocesses WHERE dbid > 0 hostprocess='123'
Hi! Do you consider publishing to the maven central?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.