Reputation: 26
I tried to load MySQL driver when my application is running. So I made jar file loading method as "loadJobJars" to that be creating URLClassLoader object with given jar file list. And I was call Class.forName method and then DriverManager.getConnection method. But it was output "No suitable driver found" on terminal.
Is there anyone know why this be happened?
My code is below.
public DBConnectionManager(Path jarPath) throws MalformedURLException {
this.urlClassLoader = loadJobJars(listJarFiles(jarPath));
}
public Connection createConnection(String dbName, String host, int port, String db, String user,
String password) throws NoSuchFieldException, SecurityException, IllegalArgumentException,
IllegalAccessException, ClassNotFoundException, SQLException, InstantiationException {
dbName = dbName.toLowerCase();
String url = "jdbc:" + dbName + "://" + host + ":" + port + "/" + db;
String driverName = DBDriver.getDriverName(dbName.toUpperCase());
Logger.getInstance().info("connection url: "+url+" driver: "+driverName);
Class.forName(driverName, true, this.urlClassLoader);
Connection conn = DriverManager.getConnection(url, user, password); //Here is it was happened code line.
return conn;
}
public URLClassLoader loadJobJars(File[] jarFiles) throws MalformedURLException {
URL[] urls = Arrays.asList(jarFiles).stream().map(f -> {
try {
System.out.println(f.getAbsolutePath());
return f.toURI().toURL();
} catch (MalformedURLException e) {
e.printStackTrace();
}
return null;
}).filter(u -> u != null).toArray(URL[]::new);
return URLClassLoader.newInstance(urls, ClassLoader.getPlatformClassLoader());
}
public File[] listJarFiles(Path jarPath) {
return jarPath.toFile().listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".jar");
}
});
}
Console output is below.
[INFO][DBConnectionManager:77][20210119152004] connection url: jdbc:mysql://localhost:3306/mysql driver: com.mysql.jdbc.Driver
Exception in thread "main" java.sql.SQLException: No suitable driver found for jdbc:mysql://192.168.1.157:3306/mysql
at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:702)
at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:251)
at com.innotree.innoquartz.iqjobgen.DBConnectionManager.createConnection(DBConnectionManager.java:35)
at com.innotree.innoquartz.iqjobgen.DBConnectionManager.main(DBConnectionManager.java:77)
Upvotes: 0
Views: 213
Reputation: 26
Thank for your kind answer.
I saw your answer and finally figure out the problem by direct loading MySQL driver. Your help was very useful to solve that. Solution code is down below.
String url = "jdbc:mysql://localhost:3306/mysql";
URLClassLoader loader = new URLClassLoader(urls, ClassLoader.getSystemClassLoader());
Class cls = loader.loadClass("com.mysql.jdbc.Driver");
Driver driver = (Driver)cls.newInstance();
Properties info = new Properties();
info.put("user", "admin");
info.put("password", "1234");
Connection conn = driver.connect(url, info);
Upvotes: 0
Reputation: 109138
The way DriverManager
creates connections is sensitive to the class loader of the calling code. The Driver
used to create the connection must be visible to the class loader of the calling class (or when the calling code has no class loader, the context class loader). The driver you loaded is not visible to the class loader of the calling code, so DriverManager
will not use the driver to create a connection.
You must create the connection using code that uses the same class loader (or at least where the class loader with the driver is visible). Alternatively, you need to use the java.sql.Driver
directly, skipping DriverManager
altogether.
Upvotes: 1