【问题标题】:How to override some classes in a jar in WEB-INF/lib with another jar in JBoss EAP?如何用 JBoss EAP 中的另一个 jar 覆盖 WEB-INF/lib 中的 jar 中的某些类?
【发布时间】:2017-08-18 10:56:34
【问题描述】:

如果要覆盖的类名为com.example.FooServlet,并且该类位于一个罐子WEB-INF/lib/foo.jar 中,那么如何用另一个罐子中也称为com.example.FooServlet 的类来覆盖它,比如bar.jar

或者有什么方法可以确保bar.jar 中的那个首先被加载?

使bar.jar 成为一个模块是行不通的,因为FooServletWEB-INF/lib 中的许多jar 中导入了大量的类。


如上所述,我试图在一个模块中包含bar.jar,但是由于FooServlet 扩展/实现了一些额外的类/接口,所以找不到类或没有类定义错误(记不清了)在 WEB-INF/lib 中的 3rd 方 jars 中。

我不允许触摸foo.jarWEB-INF/lib 中已经存在的任何罐子。

【问题讨论】:

    标签: java jboss jboss7.x


    【解决方案1】:

    你说你不能碰现有的罐子,你似乎暗示你可以添加你的罐子到WEB-INF/lib

    根据this

    • WEB-INF/lib/*.jar 下的 jar 没有指定优先顺序。
      所以如果你在里面添加bar.jar,你不知道它会在foo.jar之前还是之后加载。
    • servlet 规范说WEB-INF/classes 下的类必须在WEB-INF/lib/*.jar 下的任何内容之前加载

    假设您可以在WEB-INF/lib添加一个 jar,那么您应该可以在 WEB-INF/classes 下添加一个(或多个)类,而无需触及现有的类。
    因此,如果您希望首先加载来自bar.jar 的类,您可以改为解压缩WEB-INF/classes 下的那个jar 的内容(或者只是您想要优先加载的类——例如WEB-INF/classes/com/example/FooServlet.class)。

    【讨论】:

      【解决方案2】:

      查看 JBoss 模块以及如何通过jboss-deployment-structure.xml 部署描述符处理它们。

      很简单……

      对于 2 个不同的 WAR 文件,您可以有 2 个不同的模块,每个模块在不同的 jar 文件中具有不同的 com.example.FooServlet。

      您只需将 foo.jar 和 boo.jar 文件从 WAR 文件中取出并将它们添加到相应的模块中。

      ClassLoader for WAR 从您在 jboss-deployment-structure.xml 中定义的模块中挑选所需的类,并且不会与其他版本发生冲突。

      【讨论】:

      • 首先,由于限制,我无法从 WAR 中提取 foo.jar 并使其成为模块;其次,我试图在一个模块中包含bar.jar,但是得到了class not found 或no class def 错误(记不清了)。 FooServlet 扩展/实现了一些额外的类/接口,它们位于 WEB-INF/lib 的 3rd 方 jar 中,我无法提取它们。
      • h-m-m... 首先-这意味着您的问题在于限制-问题是关于它们的。也许可以改变以简单,标准的方式实现目标?第二 - 是关于你对模块做一些不太正确的事情。实际上它工作得很好。我还有大量 3-rd 方 jar 文件。
      • 也许您还需要将一些 3-rd 方 jar 从 WAR 移到您的模块中......否则可能有一种方法可以自己操作类加载器,但是......我'我很确定它需要做很多工作,并且会有更多未知但挑战..我仍然建议你重新考虑限制并使模块方法工作。它绝对可以满足您的需求。
      【解决方案3】:

      Java 代理注意事项

      假设您可以完全控制 JBoss 的启动方式,或者至少您可以更改 JBoss 启动设置 - Java 代理就是您的帮助。

      简而言之,Java 代理是 JVM 的自定义“插件”jar,它可以拦截该 JVM 对每个类的加载。而且 - 正是您所需要的 - 它可以执行任何拦截类的字节码的替换。 Further reading about Java agent concept

      您要实现的目标并不是全新的,而且似乎已经在某种程度上得到了解决。 查看questionanswer - 似乎有关于编写代理的完整指南,该代理根据提供的外部 jar 替换类。

      高层计划

      1. 开发您的 java 代理,编译它的 jar 并将其放置在您的 bar.jar 附近(因为代理将直接读取 bar.jar)
      2. 编辑 JBoss 启动命令行以包含 -javaagent:/path/to/your/agent.jar
      3. 现在在 JBoss 启动期间,如果您提供的 bar.jar 中存在相应的类,您的代理将用相应的类替换每个类

      根据您的 JBoss 版本和部署模型,事情可能会变得有点复杂,但是有 some guides 用于流行的代理安装,可以很容易地适应我们的情况

      【讨论】:

        猜你喜欢
        • 2012-05-18
        • 1970-01-01
        • 2012-04-16
        • 1970-01-01
        • 2016-05-19
        • 1970-01-01
        • 2022-08-16
        • 1970-01-01
        • 2011-01-31
        相关资源
        最近更新 更多