Categories
Mastering Development

Java – dynamically implement interface

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.

Leave a Reply

Your email address will not be published. Required fields are marked *