【问题标题】:How Jetty handles class loading with same class with different dependencies?Jetty 如何处理具有不同依赖项的同一类的类加载?
【发布时间】:2017-05-20 11:10:16
【问题描述】:

我想知道当多个依赖路径可能导致同一个类时,码头如何处理。

例如,

Jetty 预装了 JSTL-1.2,但我添加了一个依赖项来加载 JSTL-1.2.4。在编译时,如果我在eclipse中下载源代码进行断点测试,它会在1.2.4版本中断。

我想知道将传递哪个版本来生成JSP的字节码,当有两个版本的类时,说一些依赖的基类JstlCoreTlv(一个预先打包,即带有码头的 JSTL 1.2 和一个从 maven 依赖项 1.2.4 传递的)

简而言之,我想知道码头是如何做到的。我想知道码头如何优先考虑预打包和稍后添加的依赖项。即使版本比预打包的版本旧,它会覆盖并引用添加的依赖项吗?

在这种情况下,我无法从码头文档中获得太多信息。非常感谢您的帮助

【问题讨论】:

  • 默认行为是什么?我没有更改与类加载首选项相关的任何内容。
  • 这并没有说明当存在同一类的不同版本时会发生什么
  • 我不确定我是否理解这一点。我的实际问题是,当有两个版本的类依赖时,我想知道将传递哪个版本来生成 JSP 的字节码(一个是预打包的,即带有码头的 JSTL 1.2,另一个是从 maven 依赖项 1.2 传递的) .4).
  • 这两个类怎么能用来生成字节码呢?它可以是任何一个。更具体地说,假设一个类 JstlCoreTlv (1.2),也存在于 1.2.4 中,我的 JSP 类将在其中一个上生成,如何由两者生成?
  • 你的意思是说,它可能会在 JSP 的不同编译时间加载不同版本的 JstlCoreTlv ?

标签: java dependency-injection jetty jstl jetty-8


【解决方案1】:
  • 假设您不打算更改 Jetty 安装的 jstl 版本。
  • 假设您只使用 jstl 版本 1.2.4 来编译您的代码,并且您没有将 jar 添加到您的 war WEB-INF/lib 中。

如果您使用 maven 针对 1.2.4 进行编译和打包,并将打包好的 war 部署在 Jetty 上,Jetty 将使用 1.2(这是服务器类路径上的那个,而不是 1.2.4(因为它不适用于 Jetty)。这可能会导致问题。

避免问题的最佳方法是在 maven 项目依赖项中使用与您将部署的 Jetty 版本所使用的版本完全相同的版本。

【讨论】:

  • 如果我将所有依赖项都包含在 WAR 中会怎样?在这种情况下会发生什么?
  • Jetty 通常遵循 Servlet 规范进行类加载。请参阅eclipse.org/jetty/documentation/current/jetty-classloading.html,因此通常它应该更喜欢 WEB-INF/lib 中的 jar。但是这个 JSTL 是非常核心的 web 服务器的东西,可能还需要一些其他的依赖项。我不建议走这条路。如果你想走这条路,你可以阅读 Jetty 文档,它描述了使用的 JSTL 依赖项。注意:1.2 与 1.2.4 应该没有问题,我认为 .4 有一些错误修复,但我不希望 API 更改导致类加载问题。
  • 感谢@Escay。我将其添加为 Maven 依赖项。是的,我升级的原因是在 1.2.4 JSTL 中包含一个错误修复。那么最好的方法来更新预先打包在 1.2.4 或更高版本的码头?我没有其他方法可以告诉码头选择 1.2.4 吗?
  • 另外,参考这条评论,假设您不打算更改 Jetty 安装的 jstl 版本有没有办法在不升级 jetty 的情况下做到这一点?跨度>
  • @KarthikNarisetti 您可以简单地重命名新 jar 并将其替换为旧 jar,以便 Jetty 拾取它。您不必以这种方式升级 Jetty。
【解决方案2】:

servlet 规范要求:

  • WEB-INF/lib 或 WEB-INF/classes 中包含的类优先于父类加载器(这里是码头的类加载器)上的类。

来自document of jetty

WEB-INF 类可以替代 Server 类。

而这里的server类是j2ee标准的jetty实现(代码来自jetty source code):

    /** Is the class a Server Class.
     * A Server class is a class that is part of the implementation of 
     * the server and is NIT visible to a webapplication. The web
     * application may provide it's own implementation of the class,
     * to be loaded from WEB-INF/lib or WEB-INF/classes 
     * @param clazz The fully qualified name of the class.
     * @return True if the class is a server class.
     */
    boolean isServerClass(Class<?> clazz);

您还可以通过调用添加对服务器类的控制:

【讨论】:

  • 感谢@Tony 的投入
猜你喜欢
  • 2023-03-08
  • 2012-12-26
  • 1970-01-01
  • 2016-01-26
  • 2018-11-15
  • 1970-01-01
  • 2020-01-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多