It all depends on how your application is structured. Problems can arise due to access security implemented in Java Classloaders.
If your application manages the connection to the database, there is no problem in leaving the JDBC driver in your lib, as classes will be managed by the same Classloader.
However, if you leave the connections in charge of the application server, the driver needs to stay in the server's lib, as the classes present in this lib will be managed by another Classloader.
Note that when we talk about a complex JVM environment consisting of several Classloaders, many things that are true and simple in an ordinary Java program become false and difficult.
For example, when there are several Classloaders, there may be multiple copies of the same class in memory, whose static attributes may contain different values for each Classloader. This causes many problems.
In addition, each container assembles a Classloader Hierarchy to protect its own libraries from misunderstandings and attacks from a third-party application and also to prevent one application from interfering with another. This, for example, allows multiple instances of the same application to be "installed" on the same instance of the container.
See the example Tomcat Classloader Hierarchy :
Bootstrap
|
System
|
Common
/ \
Catalina Shared
/ \
Webapp1 Webapp2 ...
When a Java program uses or imports a class for the first time, the current Classloader queries its top-level ancestors in the hierarchy. In the case of Tomcat, if an application will load the class Pessoa
, its Classloader first checks the Shared
, which in turn checks the Commom
, which in turn checks the System
. If the class does not exist in the "parent" Classloader, then the current Classloader attempts to load the class and returns a positive or negative response to the "child" Classloader, culminating in a cascading process.
A common problem is to put a framework like Spring in the Shared
lib. When the application starts Spring, it is then found in the Classloader Shared
. However, Spring will attempt to load several classes configured in XML. When it asks your Classloader ( Shared
) to load the Pessoa
class, Classloader does not will look for the class in the Classloader "child", that is, the application Classloader, just where class is.
These rules are not exactly strict, there are settings that allow you to change the behavior of Classloader. No need to fear them, they are just Java classes with specific implementations and logics. The important thing is to understand how it works.