9
votes

From the Java documentation

In previous versions of JDBC, to obtain a connection, you first had to initialize your JDBC driver by calling the method Class.forName.

Any JDBC 4.0 drivers that are found in your class path are automatically loaded. (However, you must manually load any drivers prior to JDBC 4.0 with the method Class.forName.)

I have a jersey Webservice which connects to SQL Server Express 2016. It has sqljdbc42.jar which is 4.2 driver, in the CLASSPATH

However, if I omit the Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver") call, my DriverManager.getConnection throws a SQLException(No suitable driver found for jdbc:sqlserver://localhost:1433; ....")

The getConnection starts succeeding once I add the Class.forName call.

I am on Java 8.

What am I missing?

UPDATE: I just tried a command line program and it works without the forName. However, from my Eclipse IDE where I am running my REST service as a Tomcat 8.0 Server on localhost, it doesn't work.

1
"...sqljdbc42.jar which is 4.0 driver" Proof here, for any fellow skeptics. :-) Well, okay, it's not a 4.0 driver, it's a 4.2 driver, but...T.J. Crowder
@T.J.Crowder updated :-)user93353
If so It seems that Microsoft doesn't like to follow standardsNicolas Filotto
Check if you have a file META-INF/services/java.sql.Driver in sqljdbc42.jar, its content should be the FQN of the driver which is com.microsoft.sqlserver.jdbc.SQLServerDriver in this caseNicolas Filotto
where do you put your driver? in tomcat/lib?Nicolas Filotto

1 Answers

9
votes

The drivers are automatically initialized when the class DriverManager is itself initialized thanks to SPI (Service Provider Interface). Which means that internally it will try to find any file META-INF/services/java.sql.Driver available in the context class loader and for each file found, it will create an instance of the class that is defined in the file which in this case is actually the FQN of the JDBC driver, this is how JDBC drivers are automatically initialized starting from JDBC 4.0.

But this can only work, if your driver is available from the context class loader while initializing the class DriverManager. A good way to ensure that is to make your driver available from a Class Loader high enough in the hierarchy. In your case you should put your driver in tomcat/lib. Indeed, this way your driver will be available from the Common CL which should be high enough. More details about the CL hierarchy in Tomcat here.