1

I have a spring boot application using ms-sql database, it deploys properly in external tomcat when the server is newly started, but when I redeploy the same war file I get the following error(the war file still deploys but is not functioning properly:

Native library mssql-jdbc_auth-8.4.1.x64.dll already loaded in another classloader when I redeploy the war file in external tomcat.

So I undeploy the war file, restart the tomcat server, and redeploy it, and it's deploying properly and working (functions and CRUD).

I am using tomcat 9.0.43 and there are no other applications deployed to the server instance.

EDIT: I am running tomcat on windows and also have the .dll file in the tomcat bin folder. Also I'm using maven for dependency management.

The program uses integrated security for DB auth

askwer
  • 163
  • 13
  • Does this answer your question? [java.lang.UnsatisfiedLinkError: Native Library XXX.so already loaded in another classloader](https://stackoverflow.com/questions/36936948/java-lang-unsatisfiedlinkerror-native-library-xxx-so-already-loaded-in-another) – Piotr P. Karwasz Apr 16 '21 at 08:36
  • Try setting the `mssql-jdbc` dependency scope to `provided`, so it doesn't end up in `WEB-INF/lib`, but in `WEB-INF/lib-provided` and add the driver to Tomcat's `lib` directory. – Piotr P. Karwasz Apr 16 '21 at 08:50
  • @PiotrP.Karwasz I did what you suggested and set it to provided and it worked! the dependency was set to runtime and it's causing the redeployment issues. Thanks! – askwer Apr 16 '21 at 09:03
  • @PiotrP.Karwasz can you post your comment as an answer so I can mark this as solved? – askwer Apr 16 '21 at 09:28

1 Answers1

1

Your problem comes from the double usage you want to make of your WAR file:

  • on one side you need the JDBC driver whenever you run the WAR file using java -jar,
  • on the other side you don't want JDBC drivers in the web application's classloader, whenever the WAR file is deployed in a servlet container. The servlet container should provide the drivers.

Fortunately the spring-boot-maven-plugin already provides such a feature in the repackage goal: all the dependencies marked as provided (such as the Embedded Tomcat libraries) are placed in the WEB-INF/lib-provided folder and hence are not loaded by the servlet container.

Therefore you only need to mark the JDBC driver as provided and add it to Tomcat's common loader's classpath ($CATALINA_BASE/lib).

Piotr P. Karwasz
  • 12,857
  • 3
  • 20
  • 43