MSSQL driver is not loaded by Tomcat

2020-03-07 07:18发布

问题:

I am trying to deploy my webapp to a Tomcat container, but I get an exception stating that no driver for my database can be found. Locally I test the app on Jetty and the driver-jar is provided by Maven. I copied the driver-jar to the lib folder in the Tomcat home folder, but I still get this exception:

java.sql.SQLException: No suitable driver found for jdbc:sqlserver:<address of the database>
    at java.sql.DriverManager.getConnection(DriverManager.java:604) ~[?:1.7.0_21]
    at java.sql.DriverManager.getConnection(DriverManager.java:243) ~[?:1.7.0_21]
    at com.mypackage.ConnectionFactory.createConnection(ConnectionFactory.java:34) ~[ConnectionFactory.class:?]
    at com.mypackage.SimpleWebSession.authenticate(SimpleWebSession.java:63) [SimpleWebSession.class:?]
    at org.apache.wicket.authroles.authentication.AuthenticatedWebSession.signIn(AuthenticatedWebSession.java:65) [AuthenticatedWebSession.class:6.15.0]
    at com.mypackage.SimpleWebSession.signIn(SimpleWebSession.java:118) [SimpleWebSession.class:?]
    at com.mypackage.SignInPage$1.onSubmit(SignInPage.java:67) [SignInPage$1.class:?]
    at org.apache.wicket.markup.html.form.Form.delegateSubmit(Form.java:1272) [Form.class:6.15.0]
    at org.apache.wicket.markup.html.form.Form.process(Form.java:938) [Form.class:6.15.0]
    at org.apache.wicket.markup.html.form.StatelessForm.process(StatelessForm.java:96) [StatelessForm.class:6.15.0]
    at org.apache.wicket.markup.html.form.Form.onFormSubmitted(Form.java:770) [Form.class:6.15.0]
    at org.apache.wicket.markup.html.form.Form.onFormSubmitted(Form.java:703) [Form.class:6.15.0]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.7.0_21]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[?:1.7.0_21]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.7.0_21]
    at java.lang.reflect.Method.invoke(Method.java:601) ~[?:1.7.0_21]
    at org.apache.wicket.RequestListenerInterface.internalInvoke(RequestListenerInterface.java:258) [RequestListenerInterface.class:6.15.0]
    at org.apache.wicket.RequestListenerInterface.invoke(RequestListenerInterface.java:216) [RequestListenerInterface.class:6.15.0]
    at org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler.invokeListener(ListenerInterfaceRequestHandler.java:243) [ListenerInterfaceRequestHandler.class:6.15.0]
    at org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler.respond(ListenerInterfaceRequestHandler.java:236) [ListenerInterfaceRequestHandler.class:6.15.0]
    at org.apache.wicket.request.cycle.RequestCycle$HandlerExecutor.respond(RequestCycle.java:862) [RequestCycle$HandlerExecutor.class:6.15.0]
    at org.apache.wicket.request.RequestHandlerStack.execute(RequestHandlerStack.java:64) [RequestHandlerStack.class:6.15.0]
    at org.apache.wicket.request.cycle.RequestCycle.execute(RequestCycle.java:261) [RequestCycle.class:6.15.0]
    at org.apache.wicket.request.cycle.RequestCycle.processRequest(RequestCycle.java:218) [RequestCycle.class:6.15.0]
    at org.apache.wicket.request.cycle.RequestCycle.processRequestAndDetach(RequestCycle.java:289) [RequestCycle.class:6.15.0]
    at org.apache.wicket.protocol.http.WicketFilter.processRequestCycle(WicketFilter.java:259) [WicketFilter.class:6.15.0]
    at org.apache.wicket.protocol.http.WicketFilter.processRequest(WicketFilter.java:201) [WicketFilter.class:6.15.0]
    at org.apache.wicket.protocol.http.WicketFilter.doFilter(WicketFilter.java:282) [WicketFilter.class:6.15.0]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) [catalina.jar:8.0.8]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [catalina.jar:8.0.8]
    at org.apache.logging.log4j.core.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:66) [Log4jServletFilter.class:2.0-rc1]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) [catalina.jar:8.0.8]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [catalina.jar:8.0.8]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219) [catalina.jar:8.0.8]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) [catalina.jar:8.0.8]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503) [catalina.jar:8.0.8]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:136) [catalina.jar:8.0.8]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:78) [catalina.jar:8.0.8]
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610) [catalina.jar:8.0.8]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) [catalina.jar:8.0.8]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:526) [catalina.jar:8.0.8]
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1033) [tomcat-coyote.jar:8.0.8]
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:652) [tomcat-coyote.jar:8.0.8]
    at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:222) [tomcat-coyote.jar:8.0.8]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1566) [tomcat-coyote.jar:8.0.8]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1523) [tomcat-coyote.jar:8.0.8]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [?:1.7.0_21]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [?:1.7.0_21]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-util.jar:8.0.8]
    at java.lang.Thread.run(Thread.java:722) [?:1.7.0_21]

The driver is also in the lib folder of the app in WEB-INF/lib could this cause the exception? I am using Java 7 and version 4 of the MSSQL JDBC driver.

Update

If I write

try {
    Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
} catch (final ClassNotFoundException e) {
    // Should not happen.
    e.printStackTrace();
}

before, I get the connection. Why is it so?

回答1:

I think I got the reason. Tomcat tries to prevent memory leaks due to some particular java/javax apis and it seems that the sql server driver is one of them. If you disable that feature it should load the driver automatically. To disable, modify the server.xml JreMemoryLeakPreventionListener entry as below.

<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" driverManagerProtection="false" />