I'm refactoring a code which lazy loads a class though the thread's classLoader like this:
Thread.currentThread().getContextClassLoader().loadClass("path.to.class");
The problem is that "path.to.class" implements an interface ("Log") from a library that is selected by the App's user (so I know the driver version at runtime, not compile-time; specifically the driver is mysql-connector-java).
So I need a way to load a class as shown above but by making it implement an interface that depending on the selected version is at one package or another ("com.mysql.jdbc.log.Log" older one vs. "com.mysql.cj.log.Log" new one).
I was told to use Dynamic Proxies but I'm unable to achieve that way:
MySqlLogger mySqlLogger = new MySqlLogger("");
if (NEW_MYSQL_DRIVER_CLASS.equals(getDriverClassName())) {
Object proxy = Proxy.newProxyInstance(getClass().getClassLoader(),
new Class[] {Class.forName("com.mysql.cj.log.Log")},
new MySqlLoggerInvocationHandler(mySqlLogger));
Thread.currentThread().getContextClassLoader().loadClass(proxy.getClass().getPackage().getName());
connectionProperties.putIfAbsent(LOGGER_PROPERTY, proxy.getClass().getPackage().getName());
} else {
Object proxy = Proxy.newProxyInstance(getClass().getClassLoader(),
new Class[] {Class.forName("com.mysql.jdbc.log.Log")},
new MySqlLoggerInvocationHandler(mySqlLogger));
Thread.currentThread().getContextClassLoader().loadClass(proxy.getClass().getPackage().getName());
connectionProperties.putIfAbsent(LOGGER_PROPERTY, proxy.getClass().getPackage().getName());
}
} catch (Throwable e) {
//
}
The MySqlLoggerInvocationHandler handler implements the java.lang.reflect.InvocationHandler interface. But the thing is that I think I'm wrongly creating the proxy since once created its class is com.sun.Proxy so I can't load it as MySqlLogger.
Aucun commentaire:
Enregistrer un commentaire