【问题标题】:URLClassLoader throws No Class Definition found exceptionURLClassLoader 抛出未找到类定义异常
【发布时间】:2011-10-05 02:48:18
【问题描述】:

我有 3 个 Java 项目 A、B 和 C。 B 就像 A 的附加组件。A 和 B 都依赖于项目 C 的某些类。

现在在项目 A 中,当我使用如下 URLClassLoader 时:

URLClassLoader ucl = new URLClassLoader(urls); //urls are paths to some classes in B

现在在使用这些 ucl 时,当我在 B 中调用一些方法时,它给了我 No Class Definition found 异常。这是针对 C 类的。

现在当我使用 ClassLoader 时如下:

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
URLClassLoader ucl = new URLClassLoader(urls, classLoader);

当我调用 B 中的方法时,这很好用。 我的问题:

1) 当我使用第一种方式时,使用的是哪个 ClassLoader?我阅读了 JavaDocs,但找不到任何可以解释的内容。
2) 有没有办法获得一个特定于项目 B 的 ClassLoader,我可以以某种方式使用它,这样我就不会遇到任何依赖问题?

感谢您的帮助。

【问题讨论】:

    标签: java urlclassloader


    【解决方案1】:

    默认的类加载器是系统类加载器(加载类路径上的类)。

    如果您使用特定的类加载器加载 B 中的类,请使用该实例。否则someTypeInB.getClass().getClassLoader() 将作为一个黑客。

    (注意:使用URLClassLoader.newInstance 通常比new URLClassLoader 更可取,因为它添加了必要的安全措施(尽管还不够),以便与不受信任的代码一起使用。此外,使用线程上下文类加载器通常是个坏主意 -您引入了对本地代码的依赖,但是线程被设置和使用[可能没有任何一致的策略应用于它]。)

    【讨论】:

    • 感谢您的指点。我会调查这些事情。一个小问题。 B 就像 A 的附加组件,所以 A 对 B 一无所知。所以我不能在 A 中使用 'someTypeInB.getClass().getClassLoader()'...
    • 请注意,您可以使用this.getClass().getClassLoader() 找到您当前的类加载器。如果您只是从当前类中加载一个类,这就是您将使用的上下文。
    • @Daniel One-arg Class.forName 通常就足够了(这是一种行为非常奇怪的方法)。 @rgamber 如果我正确地遵循了您的操作,您应该为 B 创建一个类加载器,然后只保留引用以及您对 B 的任何其他指针。
    • @Daniel 用于从调用类的相同(或父)类加载器加载类。
    • 是的,但您可能还需要该类加载器,以便可以将其用作您正在创建的 CL 的父级。
    【解决方案2】:

    当您使用您的第一个 URLClassLoader 时,它仅使用 B 的路径进行初始化,然后如果 B 中的某些内容需要解析 C 中的某些内容才能加载,那么它会很短。通过使用第二种形式,你是在说“如果你在这里找不到你需要的东西,请查看'父'类加载器。”这样可以解决 C 并且每个人都开心。

    (请理解,唯一可以在不引用其他类的情况下加载的类是 Object ——即使这样也有点牵强。这不仅仅是你需要引用该类的超类——至少,基础 JDK 中的对象可以是即使没有父 CL,也会通过系统类加载器进行引用——但如果您调用另一个类的任何方法或操作指向另一个类的指针或任何此类事情,您需要解析该引用的类。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-12
      相关资源
      最近更新 更多