【问题标题】:Class in one war not able to access classes in another war of same ear一场战争中的班级无法访问同一耳朵的另一场战争中的班级
【发布时间】:2009-07-06 11:42:28
【问题描述】:

我有一个耳朵,它由 2 个 war 文件组成,一个包含 junit 类,另一个包含由 junit 引用的实际应用程序类。 现在在执行 junits 时,我得到一个 java.lang.NoClassDefFoundError

是不是因为 junit 类文件位于不同的耳朵,因此无法访问位于另一个耳朵的应用程序类文件?

这是否是由于部署问题,虽然我能够运行应用程序以及一些独立于位于另一只耳朵的应用程序类的联结?

【问题讨论】:

    标签: java jboss jakarta-ee


    【解决方案1】:

    根据严格的 JavaEE 可见性语义,WAR 中的类不应该对同一 EAR 的其他组件可见。 JBoss 对此放宽了一点,并尝试扁平化类加载层次结构以使其不那么烦人,但 WAR 限制仍然存在。

    我使用的解决方案是仅将 Web 资源放入 WAR,并将 WAR 的类文件放入 EAR 内的单独 JAR 中。这样,webapp 本身可以找到类,您的单元测试 webapp 也可以。

    【讨论】:

      【解决方案2】:

      正确的方法是将公共类移动到一个专用的 JAR 中,并在 EAR 级别捆绑它。所以你会有这样的结构:

      • 业务逻辑罐
      • main-web-app-war
      • test-web-app-war
      • 应用耳

      您可以在 EAR 中捆绑 JAR 以及您依赖的任何其他库,并使用 WAR 的清单文件引用它们。在 MANIFEST.MF 中,它看起来像:

      Class-Path: business-logic-1.0.jar spring-2.5.5.jar ...
      

      您仍然可以在每个 WAR 的 WEB-INF/lib 文件夹中捆绑额外的 JAR,例如junit 在 test-web-app-war 中。如果您使用的是 Maven,请阅读skinny war 页面了解一般方法。

      【讨论】:

      • MANIFEST.MF 中的条目应以“Class-Path:...”开头
      【解决方案3】:

      JUnit 类不属于 WAR 或 EAR 文件。不应部署它们。

      你没有说你正在使用哪个应用服务器,但如果你使用 WebLogic,你可以将所有 .class 文件放入 APP-INF/classes 中。然后它们将在 EAR 级别可见,因此所有 WAR 都可以看到它们。

      【讨论】:

      • 问题被标记为“jboss”。此外,在容器内运行测试是相当普遍的做法,因为我们并非都拥有“真正的”单元测试。
      • 错过了 jboss 标签;我在看文字。 JUnit 测试有哪些不“真实”的地方?这些都是真实的。在我看来,它们不应该被部署。
      • 我的意思是许多单元测试不是“纯”单元测试,它们需要一些环境上下文,例如在应用服务器中运行。这在遗留代码库中很常见。
      • 很公平。这些更有可能是“集成测试”。在很多情况下,可以模拟掉依赖关系。我仍然没有理由将它们打包并运送给您的客户。必须有一种方法可以锻炼它们,而不必将它们放在同一个 EAR 中。
      猜你喜欢
      • 1970-01-01
      • 2012-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-19
      • 2010-11-07
      相关资源
      最近更新 更多