Reputation: 1317
I want to develop a DB-Agnostic application in java. I have chosen hibernate as ORM. The problem with jdbc is that , it is just an interface and we need the driver class of the db in the class path. Since the database should be configurable i have to go for loading the driver class of DB dynamically. (User should keep the driver class in a folder and it should be loaded dynamically ) Below is my code.
File driverJar = new File("E:\\Jomon\\backup_2017_05_25\\2.2\\WS\\2.2_1\\lib\\Drivers\\postgresql-42.1.1.jar");
URL[] urls = new URL[] { driverJar.toURL() };
URLClassLoader classLoader = new URLClassLoader(urls,DBUtils.class.getClassLoader());
Class.forName("org.postgresql.Driver", true, classLoader);
No error till now. But after this, while initializing hibernate connection, I am getting error java.lang.ClassNotFoundException: org.postgresql.Driver.
May I know what is the problem here.
Upvotes: 2
Views: 1097
Reputation: 3892
Hibernate will always to attempt the load the driver from the current thread classloader and in your case, it doesn't have the driver.
You own class loader works fine and just before you initialize sessionFactory ,set your custom loader into contextClassLoader like this.
File f = new File( "E:\\Jomon\\backup_2017_05_25\\2.2\\WS\\2.2_1\\lib\\Drivers\\postgresql-42.1.1.jar" );
URLClassLoader urlCl = new URLClassLoader( new URL[] { f.toURL() }, System.class.getClassLoader() );
Class postGreDriver = urlCl.loadClass( "org.postgresql.Driver" );
System.out.println( postGreDriver.newInstance() );
Thread.currentThread().setContextClassLoader(postGreDriver);
//Hibernate can start
//you should restore your old classloader when hibernate services end
This may not be the best solution. Have got this snippet from this discussion
Hope this helps!!!
Upvotes: 1
Reputation: 1317
Finally I got the solution by myself, The problem here is , I have created a new classloader and loaded the jar into it.
The hibernate is searching for driver class in system class loader , not in the user defined class loaders.
The problem here can be solved by load the jar into system class loader as below.
File driverJar = new File("E:\\Jomon\\backup_2017_05_25\\2.2\\WS\\2.2_1\\lib\\Drivers\\postgresql-42.1.1.jar");
URL myJarFile = new URL("jar", "", "file:" + driverJar.getAbsolutePath() + "!/");
URLClassLoader sysLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
Class sysClass = URLClassLoader.class;
Method sysMethod = sysClass.getDeclaredMethod("addURL", new Class[] { URL.class });
sysMethod.setAccessible(true);
sysMethod.invoke(sysLoader, new Object[] { myJarFile });
Class.forName("org.postgresql.Driver", true, classLoader); // Now no error in this line.
Upvotes: 2