【问题标题】:Load Java classes based on a classpath in a properties file基于属性文件中的类路径加载 Java 类
【发布时间】:2009-04-21 19:58:59
【问题描述】:

我的应用程序使用 JDBC 数据库驱动程序。我从一个 jar 文件加载这些文件,对于我目前正在使用的 DB2,我是 db2jcc.jar。在类路径中使用这个 jar,一切都很好,但我需要从应用程序配置文件中的属性中找到 jar - 例如,

database.driver=/opt/IBM/db2/V9.5/java/db2jcc.jar

我可以通过 URLClassLoader 加载类,但问题是我需要将这样创建的对象视为显式 DB2XADataSource。例如:

URLClassLoader dbClassLoader = new URLClassLoader(new URL[]{driverJar});
xaClass = dbClassLoader.loadClass("com.ibm.db2.jcc.DB2XADataSource");

DB2XADataSource dataSource = (DB2XADataSource) xaClass.newInstance();

dataSource.setCurrentSchema(DATABASE_SCHEMA); // <- dataSource has to be a 
dataSource.setDatabaseName(DATABASE_NAME);    // DB2XADataSource to do this

(重新排列和重命名;我实际上在包含此代码的类的构造函数中执行 loadClass,而 newInstance 在其方法之一中。)

我想我陷入了类加载器的混乱,因为加载我的类的类加载器试图找到 DB2XADataSource 以进行强制转换,但 URL 类加载器不在树中它的上方。问题是,在我应该停止工作一天之后(在英国),我想不出如何以一种模糊而理智的方式最好地解决它。

想法?

谢谢。

【问题讨论】:

    标签: java jdbc properties classpath


    【解决方案1】:

    最简单的方法是只使用 java.beans API(或直接反射,如果必须的话)来调用 setter 方法。

    或者:您的数据库代码需要链接到动态加载的代码。因此,动态加载您的数据库代码。多少取决于你。除了“引导程序”之外,您几乎可以加载所有内容。

    【讨论】:

      【解决方案2】:

      是的 - 该类无法加载自己的依赖项。你可以做一些 ClassLoader 魔术,但我想它很快就会变得一团糟。

      减少反射量的一种方法是将任何依赖于 DB2XADataSource 的代码放入通过调用 ClassLoader 可用的接口调用的实现中。

      //in mydb2driver.jar
      public class MyDb2Driver implements IDriver {
      
          private DB2XADataSource dataSource = new DB2XADataSource();
      
          public void init() {
              dataSource.setCurrentSchema(DATABASE_SCHEMA);
          }
      
          //etc.
      
      }
      

      这是与您的驱动程序一起加载的:

      database.driver=/opt/IBM/db2/V9.5/java/db2jcc.jar:/foo/mydb2driver.jar
      

      调用代码在常规类路径中:

      public interface IDriver {
          public void init();
          //etc.
      }
      
      ...
      
      URLClassLoader dbClassLoader = new URLClassLoader(new URL[]{driverJar});
      xaClass = dbClassLoader.loadClass("foo.MyDb2Driver");
      IDriver dataSource = (IDriver) xaClass.newInstance();
      dataSource.init();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-03-10
        • 2016-05-23
        • 1970-01-01
        • 2014-05-01
        • 1970-01-01
        • 2014-12-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多