【问题标题】:JAVA ClassLoad same class nameJAVA ClassLoad 相同的类名
【发布时间】:2012-09-17 10:31:56
【问题描述】:

昨天想了一个问题,下面是详细内容:

我有 3 个 JAR 文件,a.jarb.jarc.jar。这两个 jars 文件都有一个名为 com.test.Test 的类,并且在该类中定义了 sayHello()

我创建了一个 Web 应用程序,我引用了 a.jar,b.jar,c.jar 。在主要方法中,我涉及 sayHello(); .此时,将加载哪个com.test.Test?

结果是一个.jar。

有人告诉我原因吗?提前谢谢!!!

【问题讨论】:

  • 您可以通过使 sayHello 方法打印与其他方法略有不同的内容来轻松地自己测试它。
  • 是的,我做到了。 a.jar 已加载。我想知道为什么:)
  • 对不起。我错过了您回答自己问题的部分。

标签: java jakarta-ee


【解决方案1】:

这就是 java language specification 所说的。它加载类第一次出现在 classpath 中并忽略其他的。

【讨论】:

  • 为什么 b.jar 不是第一个出现在类路径中。
  • 类路径由您设置。您可以修改类路径并将 b.jar 作为第一个,将 a.jar 作为第二个。为什么 b.jar 排在第二位?你需要告诉我们。 JVM 不会限制你移动,除非 b.jar 对 a.jar 有一些依赖。
  • 好的,但是如果在网络应用程序中?我把这些jar放在/web-inf/lib/下。我没有修改类路径。
  • 如果它们在WEB_INF/lib中,你无法控制。正如 Edwin 所建议的,您需要重新考虑您的包装结构。
  • 类路径中有多个 jar 的东西是 jar-hell 的一个很好的例子 :-) 你可能对 JBoss 模块或 OSGi 感兴趣,它允许你将 jar/类放入不同的包/模块中对指定客户端可见。
【解决方案2】:

与其关注将加载哪个,不如意识到 JAR 文件中的内容可能需要他们的 com.test.Test 类而不是其他人的 com.test.Test 类好好工作。这意味着对于一个功能系统,您必须找到一种方法,让a.jar 找到a.jar's com.test.Test 而不是b.jar 中的那个。 b.jar 发现它的类优先于 a.jar's 也是如此。

做到这一点的唯一方法是使用一个添加名称间距java包机制的框架。这通常使用多个类加载器来完成,通常每个 JAR 文件一个。您可以自己编写这样的东西 (Tomcat did),您需要在其中指定跨加载器发现的规则,或者使用类似于 OSGi 框架的东西。

【讨论】:

  • 我只是想知道 Web 应用中 ClassReload 的机制。
  • 没有真正的“重新加载”。 Web 应用程序取消引用“持有”类加载器并创建一个新的,然后通过初始化例程发送新的,读取 web.xml 并根据配置加载类。旧的(当被推迟时)变得无法被 JVM 的执行主线程访问,并被垃圾收集(这也将垃圾收集以前类定义的所有先前知识)。
  • 我在想Loader是否比较每个jar文件名的ASCII码,例如:a==>65, b==>66,所以a.jar被加载了。我也试过其他名字。
  • @user1698495 这不是怎么做的。它的工作原理有很好的记录,您可以在此处阅读文档。 docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html 如果它不能那样工作,那就不是 Java。
  • 好的,让我先检查一下这个文档。谢谢好友...我整晚都在关注这一点,稍后会去办公室:((
【解决方案3】:

将使用类路径中最先出现的 Jar 文件。 您可以将CLASSPATH 环境变量修改为您的Jar 文件的路径

假设你修改如下: -

set CLASSPATH = %CLASSPATH%;.;a.jar;b.jar

然后将使用 a.jar..

您也可以通过以下方式对其进行修改:-

set CLASSPATH = %CLASSPATH%;.;b.jar;a.jar

在这种情况下,将使用 b.jar.. 您需要从您的Command Line..运行这些命令。

** 注意: - 如果您使用任何 IDE,则它们不使用系统类路径。您需要为您使用的 IDE 设置不同的类路径。

【讨论】:

    【解决方案4】:

    如果您使用的是 IDE,例如 eclipse,您可以在项目的属性上修改类路径,然后转到 Build Path,然后您有 Order and Export 选项卡,您可以在其中上下移动 jar .顶部的一个将是您的应用程序首先采用的。

    您也可以手动执行此操作,方法是编辑项目中名为“classpath”的文件,然后将您希望应用程序首先使用的 jar 移至顶部。

    【讨论】:

    • 是的。对于java项目,这是可以做到的。在 Web 应用程序中如何使用 la?因为你不,我们只是把 jar 文件放在 /lib/...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-06
    • 2014-11-13
    • 2012-07-31
    • 2017-09-26
    • 1970-01-01
    • 2020-03-20
    相关资源
    最近更新 更多