I happily used DBCP and DBCP2 with Spring for over a decade. I am now trying to migrate from Java 8 to Java 11 and hit a terrible snag, described below:
* My apps dynamically load the classpath from a tree of folder that contains many JARs. Yes, I can change this model in the future but for now I need to migrate many apps quickly and that means keeping this design. * The old techniques to do the above broke starting in Java 9, so I must now use a custom classloader. That was easy to write, and I set it with thread.setContextClassLoader(myClassloader). From that point on in "vanilla" Java my apps find the classes fine as all the needed libraries are in the classpath. * But I define my DBCP2 DataSource in a Spring context.xml file. This is where things break. o I get a ClassNotFoundException for org.apache.commons.pool2.ObjectPool when loaded indirectly by the Spring bean specified with class="org.apache.commons.dbcp2.BasicDataSource". o Curiously, I can successfully load the class manually with myClassloader.loadClass("org.apache.commons.pool2.ObjectPool") in my code just fine, confirming that it is properly on the classloader's classpath. * My conclusion (maybe erroneous) is that Spring is reverting to the system classloader instead of using myClassloader when loading classes, because at the time of execution (and exception) the commons-pool2 JAR is only known to myClassloader, not the system classloader. I suspect that the core of this problem is more about Java 11 or even Spring than DBCP2. But as most applications that rely on DBCP2 do it through Spring, a lot of us are migrating out of Java 8, and this issue cripples those DBCP2-reliant applications... I am hoping that there is a well-known solution and someone here will be kind enough to share it. Thank you in advance.