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

时间:2017-08-18 10:56:35

标签: java jboss jboss7.x

如果要覆盖的类被调用com.example.FooServlet并且此类在jar WEB-INF/lib/foo.jar内,那么如何使用另一个jar中名为com.example.FooServlet的类覆盖它,比如说{{1} }}?

或者有没有办法确保首先加载bar.jar中的那个?

制作bar.jar模块是不行的,因为bar.jar会从FooServlet中的许多广告系列中导入大量的类。

正如我上面所说,我试图在一个模块中包含WEB-INF/lib,但是找不到类或没有类def错误(不能清楚地记得),因为bar.jar扩展/实现了一些额外的类/ WEB在WEB-INF / lib中的第三方jar中的接口。

我不允许触摸FooServletfoo.jar中已存在的任何广告。

3 个答案:

答案 0 :(得分:2)

你说你无法触及现有的罐子,你似乎暗示你可以添加你的罐子到WEB-INF/lib

根据this

  • WEB-INF/lib/*.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的内容(或者只是要优先加载的类 - 例如{ {1}})。

答案 1 :(得分:1)

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

很简单......

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

您只需要将您的foo.jar和boo.jar文件从WAR文件中删除,然后将它们添加到相应的模块中。

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

答案 2 :(得分:1)

Java代理注意事项

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

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

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

高级计划

  1. 开发你的java代理,编译它的jar并放在bar.jar附近(代理将直接读取bar.jar)
  2. 编辑JBoss启动命令行以包含-javaagent:/path/to/your/agent.jar
  3. 现在,在JBoss启动期间,如果您提供的bar中存在相应的类,您的代理将替换每个类.jar
  4. 根据您的JBoss版本和部署模型,事情可能会变得有点复杂,但是有some guides用于流行的代理安装,可以很容易地适应我们的情况