如何用 JBoss EAP 中的另一个 jar 覆盖 WEB-INF/lib 中的一个 jar 中的一些 类?

How to override some classes in a jar in WEB-INF/lib with another jar in JBoss EAP?

如果要覆盖的 class 称为 com.example.FooServlet 并且此 class 在罐子 WEB-INF/lib/foo.jar 中,如何用 class 覆盖它在另一个罐子里叫 com.example.FooServlet,说 bar.jar?

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

制作 bar.jar 模块是不行的,因为 FooServletWEB-INF/lib.

中的许多 jar 中导入大量 classes

正如我上面所说,我试图在一个模块中包含 bar.jar,但是没有找到 class 或者没有 class def 错误(记不清了)作为 FooServlet extends/implements 一些额外的 classes/interfaces 位于 WEB-INF/lib.

的第 3 方罐子中

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

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

很简单...

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

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

WAR 的类加载器从您在 jboss-deployment-structure.xml 中定义的模块中选择需要的 class(es),并且从不与其他版本冲突。

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

根据this

  • WEB-INF/lib/*.jar 下的 jar 没有指定的优先顺序。
    所以如果你在里面加上bar.jar,你不知道是在foo.jar之前还是之后加载。
  • servlet 规范说 classes under WEB-INF/classes must be loaded before anything under WEB-INF/lib/*.jar

假设你可以WEB-INF/lib下添加一个jar,你应该能够在WEB-INF/classes下添加一个class(或几个) , 没有接触到位的。
因此,如果您希望首先加载 bar.jar 中的 classes,您可以解压 WEB-INF/classes 下的那个 jar 的内容(或者只是您想要的 class优先加载 -- 例如 WEB-INF/classes/com/example/FooServlet.class).

Java 代理考虑

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

简而言之,Java 代理是 JVM 的自定义 'plugin' jar,它可以拦截该 JVM 对每个 class 的加载。并且 - 正是您所需要的 - 它可以执行任何截获的字节码的替换 class。

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

高层计划

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

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