【问题标题】:Load classes from folder without specifying the package从文件夹加载类而不指定包
【发布时间】:2012-02-08 14:46:24
【问题描述】:

我有一个应用程序,它允许人们使用抽象类编写自己的实现。我将这些实现作为 .class-files 从目录加载。目前,我有这个解决方案:

File classDir = new File("/users/myproject/classes/");

URL[] url = { classDir.toURI().toURL() };
URLClassLoader urlLoader = new URLClassLoader(url);

String filename;
for (File file : classDir.listFiles()) {
    filename = string.getFilenameWithoutExtension(file);
    if (filename.equals(".") || filename.equals("..") || filename.startsWith("."))
        continue;

AbstractClass instance = (AbstractClass)urlLoader
    .loadClass("org.mypackage." + filename)
    .getConstructor(ConfigUtil.class, DatabaseUtil.class, StringUtil.class)
    .newInstance(config, database, string));

    instance.doSomething();
}

如您所见 - 我需要指定类所在的包才能正确加载它们。省略包,我得到一个

 java.lang.NoClassDefFoundError:
     MyClass (wrong name: org/mypackage/MyClass)

错误。

现在,从架构 POV 来看,我认为其他人设计的类在加载时必须编译到 MY 包中,这是非常糟糕的设计。

所以我问你:有没有一种方法可以从文件系统中加载类,而不必指定它们所在的包?

【问题讨论】:

  • 您可以将包结构保留为路径下的文件夹结构吗?并在加载类之前从路径中创建包名?
  • 这是可能的……至少这样我就不必在两个班级同名时为自己烦恼了……从另一个角度思考很好! :)
  • 试试看它是否有效,如果你想要一些代码示例,请告诉我!

标签: java classloader urlclassloader dynamic-class-loaders


【解决方案1】:

是的;实现一个接口(或使用注释)。

然后使用任何类扫描库(有很多关于此的 SO 问题,例如 this one)来加载有问题的特定类。搜索“Java 类扫描”或“Java 插件机制”会有所帮助。

您可能还只想使用Java Plugin Framework 并避免一些努力。虽然我不清楚它是否已被维护,但我知道人们仍在使用它。

【讨论】:

  • 在我的情况下,我认为界面不能正常工作(从语义上讲)。 AbstractClass 有许多预定义的函数,它们只使用实现的覆盖(覆盖的被动,wtf?)方法。接口不允许这样做。
  • @FlorianPeschka ... 相同的区别。
  • 我不明白你的评论。有什么区别?
【解决方案2】:

您可以使用ServiceProvider 加载您不知道的实现。

【讨论】:

    猜你喜欢
    • 2016-06-09
    • 1970-01-01
    • 1970-01-01
    • 2011-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-19
    相关资源
    最近更新 更多